ZennoPoster, взаимодействие с приложениями на других языках программирования, обмен информацией, особенности и ошибки.

specialist

Client
Регистрация
28.12.2018
Сообщения
679
Благодарностей
275
Баллы
63
Данная статья технического характера. Много теории и частичное описание практик работы, которые когда-то были использованы при создании шаблонов.

ZennoPoster отличный инструмент для решения широкого круга задач. Универсальный и достаточно популярный язык программирования C# позволяет создать шаблон любой сложности.
Хотя сложность ничем не ограничена, время необходимое на реализацию, сложность отладки и недостаток знаний для разработки с нуля часто заставляет нас использовать готовые программы, скрипты и библиотеки чужой разработки.
Так появляются гибридные решения, когда кроме шаблона, вместе с ZennoPoster работают другие программы и скрипты.
Связь двух или более программ возможна различными способами, которые возможно сгруппировать по используемым физическим устройствам:
  • Жесткий диск
  • Оперативная память
  • Сетевая карта
В зависимости от операционной системы появляются особенности обработки входящей и исходящей информации, например UNIX socket в виде файла, по факту обеспечивающий сетевой обмен или блокировка файлов в WINDOWS при открытии программой.
Всё это заставляет нас дальше искать готовое, получая программу над программой управляемые другой программой.
Типовой обмен информацией происходит через:
  • Файлы
  • Базы данных
  • Сеть
Более редкие варианты обмена:
  • Буфер обмена
  • Жесткий диск в оперативной памяти
  • Прямое чтение из участка памяти или жесткого диска
  • Распознавание изображений с экрана
Кроме готовых программ, бывает необходимо выполнить готовые скрипты на других языках, отличные от C#, например JavaScript, Python, PHP, Ruby или просто получить результат работы консольных программ.
Необходимо учитывать особенности, связанные с кодировками текста и размерами передаваемых данных.
Не получится прочитать вывод (ошибка или будет не читаем) с русскими буквами из консольной программы в MS DOS (cp866), если попытаться запустить из-под Windows (cp1251) без перекодировки. Так же сюрприз может ожидать при запуске скрипта на Python 3 (utf8, bytes)
Ограничение длины строки в cmd 8191 символ, означает, что мы не можем передать огромный текст в виде параметра для обработки и получить обратно соответственно. Точнее Windows передаст больше, но вернет только часть.
Все особенности невозможно учесть, но понимая общие принципы хотя бы понимаешь, где возможна ошибка и какие пути для обхода.
Например, ограничение на длину строки возможно обойти читая данные из файла или развернув локальный веб-сервер, в случае скрипта. Для кодировки часто бывает достаточно добавить дополнительный параметр, указывающий на кодировку.

Часть инструментов уже готова и встроена в ZennoPoster, например кубик «Запуск программы».
При использовании действия запуска, нужно учитывать тип программы. Аргументы передаются простой строкой, всё остальное на усмотрение программы, разделителем может быть как пробел, так и тире или другой тип разделителя.

Консольные

46647


Так консольные, возвращают результат, в виде стандартного текстового потока вывода STD OUT, из которого можем получить результат выполнения запущенной программы. Поток ошибок STD ERR при успешном выполнении чаще всего пустой, но не обязательно, там могут быть предупреждения, ориентироваться на его длину для определения ошибки можно только, если точно знаешь, что там должно быть пусто.
Для примера, попробуем архивировать файлы, через консольную утилиту RAR.
Прочитав документацию, видим примерно такой способ использования консольного rar архиватора, чтобы архивировать все текстовые файлы в папке.

C#:
rar a backup.rar c:\work\doc\*.txt
Попробовав запустить шаблон, получаем интересный результат. Архив создан, только где его найти, не понятно.

Файл архива создался рядом с исполняемым файлом Rar.exe, а не в папке шаблона.

Существует несколько способов указания пути для сохранения:
  • Самый простой, это указание полного пути для сохранения данных, если программа позволяет это сделать.
  • Если позволяет структура шаблона и способ работы запускаемой программы, то файл достаточно положить рядом с шаблоном, тогда и файлы будут рядом.
  • Использовать более гибкий вариант через C# или BAT файл, когда вначале меняется директория выполнения, после запускается программа.
  • Добавить программу в системные пути, тогда сможем запускать только указав имя программы и параметры.
Иногда нужно передать в параметрах большой объем данных, например часть текста для обработки. Тут нужно обращать внимание на два момента. Первый – нужно учитывать ограничение в 8191 символ, во-вторых, нужно помнить про особенности использования некоторых управляющих символов, например слешей, кавычек, тире для nix систем.

Когда программу делали мы сами, например, при использовании скрипта на python, php – то вначале возможно зашифровать данные в base64, для расшифровки использовать обратные функции дешифрования. Таким образом возможно передать строку, обычно html код.

Запуск консольных скриптов на Python, PHP, JavaScript

46648


Единственной особенностью, для запуска скриптов является необходимость запуска интерпретатора.
Т.е. вначале запускаем программу интерпретатор, после скрипт, которому задаем параметры запуска. Единственным отличием будет то, что имя скрипта мы задаем в строке параметры запуска.

Все выше сказанное по поводу директории выполнения программы верно и для скрипта, но за счет гибкости уже внутри скрипта мы можем задать необходимые пути.
Для запуска JavaScript использовать node или v8, для python соответствующую версию интерпретатора.
Большинство скриптов возможно объединить в виде исполняемого EXE файла. При этом теряем в скорости выполнения, т.к. это просто архив, который сам выполняется, но можем спокойно передавать клиенту, не нужно думать, что у него установлено.
В случае скриптов у нас есть возможности просто читать их из файла и исполнять внутри программы, например JavaScript. Так не получится сделать со сложными скриптами, завязанными на особенности системы и другие скрипты, но простые скрипты, например скачать с сайта скрипт, отвечающий за контрольную строку, выполнить в зенопостере и получить результат бывает возможно.

Оконные программы

46649


Оконные программы очень редко проектируются для возможного запуска из консоли, поэтому не возвращают данных в стандартный ввод-вывод, обычно только код запуска.
Поэтому в настройках шаблона нужно выставлять флаг – не ждать завершения работы, иначе шаблон выдаст ошибку, действие будет выполнено почти моментально, но таймаут никак не повлияет на правильность, т.к. нет стандартного вывода.

С оконным интерфейсом существует сложность с обратным получением данных. Без особого труда можно получить заголовки, но для исследования содержимого нужно использовать WinAPI, распознавание с экрана или обмен через файлы и базы данных.

Файловый обмен с другими программами из ZennoPoster

46652

При обмене информацией через файлы, одна программа должна успеть записать данные полностью, другая узнать, что данные появились. Особенно актуальным становится данное действие при многопоточном выполнении.
Чтобы узнать о появлении данных, самый простой вариант, это проверить существует ли данный файл или папка. Но данные могут записываться достаточно долго, когда файл уже создан. Контрольную сумму просчитать чаще всего невозможно, поэтому решение данной проблемы – это дополнительный файлы маркеры.

Данный способ очень часто используется в браузерах, пока файл полностью не скачан, рядом с ним лежит другой файл. По нему мы можем узнать, завершена ли загрузка.

Таким же образом, через C# создаем вначале файл маркер, например с расширением *.zpblocked,
и проверяем наличие именного его в папке. Пока файл не будет удален, то не читаем данные.
Аналогично можем ориентироваться на временные файлы других программ.
Часто бывает, что упираемся в скорость жесткого диска, когда процессор еще свободен.

По умолчанию ZennoPoster пишет данные в текстовом виде. Это удобно и в большинстве случаев вполне приемлемо по скорости. Но когда скорости начинает не хватать, нужно переходить с текстовой на бинарную запись данных или использовать архиваторы, которая гораздо быстрее, т.к. требует меньшее количество преобразований и компактнее. Запись и чтение в специальных форматах не самое простое занятие, особенно при интеграции, так мы переходим к базам данных.

О базах данных

46654


Не вдаваясь в тонкости строения баз, можно разделить их по способу хранения информации на жестком диске и в оперативной памяти.
Базы на жестком диске, так же будут упираться в его производительность, которой может не хватать, поэтому не всегда переход с файлов на базы решает проблемы.
Некоторые из баз данных в памяти – для надежности скидывают данные на жесткий диск. В результате, когда данных слишком много, начинаются тормоза, хотя их и не ждали.
На чтение, почти все базы данных работают без задержек. Для записи используются различные блокировки, которые бывают:
  • На уровне всей базы
  • На уровне таблицы
  • На уровне строки или колонки
Базы, которые блокируются полностью, не позволяют записывать быстро в многопоточном режиме, только в один поток. К таким базам относится SQLite, MS Access, большинство встраиваемых баз данных. Они отлично подходят, когда нужно много получать данные и не часто записывать.
Блокировка на уровне таблицы, например в MySQL для некоторых типов движков, позволяет записывать достаточно быстро данные, но чем больше таблица, тем медленнее скорость записи.
Переход на другой движок таблицы внутри MySQL решает проблему, путем блокировки конкретной строки. Данные пишутся быстрее, но и ресурсов расходуется больше.
Для записи в многопоточном режиме даже с учетом блокировок самой базой возникают проблемы, когда нужно контролировать, чтобы одна запись не была изменена несколько раз.
Самый простой способ контроля – временная метка, или метка в другой таблице базы, когда вначале резервируем место, после записываем.

Особенности буфера обмена
Буфер обмена Windows позволяет хранить форматированные данные и текстовые. При запросе информации из буфера, это определяется в параметрах вызова.

В ZennoPoster нет кубика для работы с буфером, но есть C#, на котором прочитать и записать данные в буфер обмена достаточно легко.
46658

Данные могут попадать в буфер не только с помощью программы, но и человек за компьютером может что-то скопировать, так что данный способ очень ненадежный.
Для работы в несколько потоков, буфер обмена почти не пригоден. Скорость обмена хотя и высокая, но из-за двух действий копировать-вставить и вызова с небольшими задержками не самый быстрый вариант. Какой поток вызвал действие, и кто скопировал данные, возможно понять только с метками, но, чтобы считать метку, нужно постоянно заниматься запросами данных.

Сетевой обмен данными

Когда приложение работает на одном компьютере или внутри одной сети, то для обмена данными между программами, возможно использовать сокеты, как самый быстрый и хорошо документированный способ. В C# уже есть класс HttpListener для прослушивания сообщений, как и готовые клиенты. Относительная сложность появляется уже в процессе работы, когда приходится обрабатывать исключения и ошибки, т.к. тестовые данные почти всегда отличаются от тех, что реально приходят. Многопоточный обработчик обрабатывающий множество запросов сделать еще сложнее, нужно многое знать и вдаваться в тонкости.
Поэтому чаще всего берут уже готовый веб-сервер или базу данных и на них перекладывают обработку запросов.
Ограничения cmd тут уже не действуют, поэтому мы можем запустить наши скрипты как сайты и обрабатывать любой по размеру объём информации. Внутри будут тоже ограничения на размер фрагмента данных, но за счет пакетной передачи данных, разницу уже не увидим.

В ZennoPoster уже есть всё необходимое для работы с веб (http запросы, браузер, подключение к базам), с множеством примеров в официальной документации и на форуме.

46659


Взаимодействие с NoSQL базами данных рассмотрено менее подробно.
У большинства из них есть интерфейс взаимодействия через HTTP запросы. Есть официальные драйвера для C# которые по факту только создают запросы через обертку. Поэтому, когда нужна производительность, посмотрите быстро исходники драйверов, если там запросы, лишнее тащить в шаблон не нужно.

Особенности сети в Windows
В Windows в системной директории C:\Windows\System32\drivers\etc находится файл hosts который позволяет вручную сопоставлять IP адрес и доменное имя в сети.
Чаще всего этот файл используют при разработке сайтов, перенаправления трафика на нужные сервера. Но его можно использовать и для того, чтобы снизить затраты трафика у себя. Например, заблокировать рекламу или не очень важные сервера со скриптами, оставив только нужные.
В примерах часто пишут только 127.0.0.1 указывая на локальный компьютер, но на самом деле это диапазон 127.0.0.1 — 127.255.255.255, множество потоков можем запустить без пересечения, только указывая разные IP (проверять хост всё равно нужно).
Когда мы отправляем запросы на другие сервера уже вне локальной сети, нам не нужны принтеры, видимость других компьютеров. Поэтому в настройках подключения, если убрать всё лишнее, оставив только IPv4, IPv6 (тоже можно убрать, если не используем) получим очень небольшой прирост производительности за счёт снижения нагрузки на оборудование.
В реестре осталось достаточно много параметров для настройки, например количество ошибок и таймауты, которые можно изменить.

Тема обмена и ускорения работы достаточно широкая, сложно описать всё что знаешь, поэтому жду вопросов в комментариях, на которые постараюсь ответить.
 
Категория
Полезно
Последнее редактирование модератором:

DenisK

Client
Регистрация
28.06.2016
Сообщения
363
Благодарностей
151
Баллы
43
Статья больше для новичков.
 

vrska

Client
Регистрация
07.02.2010
Сообщения
378
Благодарностей
222
Баллы
43
Да, для новичков, зато как грамотно написано.
 

specialist

Client
Регистрация
28.12.2018
Сообщения
679
Благодарностей
275
Баллы
63
Статья больше для новичков.
Подробности любой темы, это будет минимум отдельная статья, лучше на вопросы отвечу, пользы будет больше.

Как сохранять результат bat'ника в txt файл? Стандартный способ "> text.txt" не работает
В кубике нужно прописать вот таким образом
46669


Так как переправили стандартный вывод в файл, то в программе ZennoPoster результат не получим. Будет создан файл.

> - перезапись
>> - дописать

указываем как параметры запуска.

При использовании C# кода будут особенности, например указание знака собаки @ указывающей на экранирование последовательности.
 
  • Спасибо
Реакции: zennoX и inilim

specialist

Client
Регистрация
28.12.2018
Сообщения
679
Благодарностей
275
Баллы
63
А таки образом как?
Это не bat файл, это обычный php скрипт. Предположим, что редактировать не можем или не хотим ..., если хотели бы, указали параметром запуска путь к файлу с результатом.

Создаем рядом с шаблоном файл test.bat, с кодом

C#:
C:\Users\home\Desktop\php\php.exe C:\Users\home\Desktop\php\test.php
При запуске указываем в поле исполняемый файл test.bat
и параметры запуска >txt.txt
 
  • Спасибо
Реакции: inilim

inilim

Client
Регистрация
16.09.2017
Сообщения
321
Благодарностей
101
Баллы
43
Это не bat файл, это обычный php скрипт. Предположим, что редактировать не можем или не хотим ..., если хотели бы, указали параметром запуска путь к файлу с результатом.
Кубик "Запуск программы" генерирует временный батник.
Заполняя поля мы на выходе получаем невидимый глазу bat файл, который исполняется и удаляется. Разве это не так работает?
Ваш случай решает задачу, за это спасибо, но все же, если мне вздумается изменить txt файл, или в работе шаблона постоянно менять файл скриптов, и т.д. Можно конечно в ZP создавать txt файл, вставлять туда команду, менять формат на bat и уже потом ваше решение, но это все костыли.
 

specialist

Client
Регистрация
28.12.2018
Сообщения
679
Благодарностей
275
Баллы
63
Кубик "Запуск программы" генерирует временный батник.
Не могу сказать однозначно, особенности работы программы лучше уточнять у их разработчиков, но скорее всего используется класс System.Diagnostics
Значит код примерно такого содержания
C#:
using System.Diagnostics;
C#:
// Use ProcessStartInfo class

        ProcessStartInfo startInfo = new ProcessStartInfo();

        startInfo.CreateNoWindow = false;

        startInfo.UseShellExecute = false;

        startInfo.FileName = "dcm2jpg.exe";

        startInfo.WindowStyle = ProcessWindowStyle.Hidden;

        startInfo.Arguments = "-f j -o \"" + ex1 + "\" -z 1.0 -s y " + ex2;
Посмотрев документацию, мы видим, что в этом случае запускается процесс, а не самостоятельный bat файл.
 

inilim

Client
Регистрация
16.09.2017
Сообщения
321
Благодарностей
101
Баллы
43
Посмотрев документацию, мы видим, что в этом случае запускается процесс, а не самостоятельный bat файл.
Один бы хрен, генерируется процесс, выполняется, очищается. Это тоже самое что создать файл, выполнить, удалить.
Ну да ладно, ушли от темы. Надо у админов узнать.
 

specialist

Client
Регистрация
28.12.2018
Сообщения
679
Благодарностей
275
Баллы
63
генерируется процесс, выполняется, очищается
Не совсем так, например, программы в пакетном файле выполняется по порядку, чтобы создать этот файл нужны права для записи на диск, будет всплывать черное окно, может зависнуть ожидая завершения и т.д., отличий достаточно.
Ну да ладно, ушли от темы. Надо у админов узнать.
ок
 

sergio197675

Client
Регистрация
21.09.2019
Сообщения
16
Благодарностей
2
Баллы
3
Подробности любой темы, это будет минимум отдельная статья, лучше на вопросы отвечу, пользы будет больше.



В кубике нужно прописать вот таким образом
Посмотреть вложение 46669

Так как переправили стандартный вывод в файл, то в программе ZennoPoster результат не получим. Будет создан файл.

> - перезапись
>> - дописать

указываем как параметры запуска.

При использовании C# кода будут особенности, например указание знака собаки @ указывающей на экранирование последовательности.
Просьба помочь разобраться с кодировками. Как в переменную (STD OUT), получить корректный ответ , если там ( в ответе ) английский и кирилица? В txt файл пишет корректно, если например , дописать chcp 855...А в STD OUT , разные варианты пробовал - не получается..
 

specialist

Client
Регистрация
28.12.2018
Сообщения
679
Благодарностей
275
Баллы
63
дописать chcp 855...А в STD OUT , разные варианты пробовал - не получается..
Возможно использовать вызов в нужной кодировке через C# кубик
C#:
process.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(855);
Но если вариантов не так много, то возможно перекодировать уже полученный ответ методом convert

примерно какт-то так, должно работать, но код не проверил
C#:
Encoding utf8 = Encoding.GetEncoding("utf-8");
Encoding cp855 = Encoding.GetEncoding("cp855,");
byte[] utf8Bytes = cp855.GetBytes(source);
byte[] cp855Bytes = Encoding.Convert(cp855, utf8, utf8Bytes);
source = cp855.GetString(cp855Bytes);
return source;
Но в основном все программы под дос раньше были в cp866, а с 855 выдавали ошибки кодировки, если не сработает - попробуйте 866 кодовую страницу
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)