Как автоматизировать Perl-скрипт в Delphi? - PullRequest
3 голосов
/ 12 ноября 2009

В настоящее время я работаю в приложении Delphi. Мне нужно запустить Perl-скрипт из приложения Delphi. Чтобы быть более понятным, мы вручную выполняем скрипт perl в окне unix. Теперь мне нужно автоматизировать выполнение этого Perl-скрипта из приложения.

Я пытался использовать ShellExecute:

ShellExecute(Handle, 'open', PChar('C:\loaderperl.bat'), nil, nil, SW_SHOW);

Окно мигает секунду и закрывается. Я не знаю, был ли выполнен сценарий или нет.

Привет, Спасибо за все ваши ответы и извините за поздний ответ. Тем не менее я борюсь с этой автоматизацией. Теперь я объясню процесс ясно, в настоящее время я открываю окно замазки, подключаюсь к удаленной машине и выполняю сценарий perl. Сценарий perl, в свою очередь, вызывает процедуру сохранения и обновляет таблицу. Теперь я хочу сделать описанный выше процесс автоматически, нажав кнопку. Поэтому, когда я нажимаю кнопку, она должна вызывать функцию, которая подключается к удаленной машине, а затем выполняет сценарий perl. Я вам понятен ??? Пожалуйста, помогите решить эту проблему. Мне нужен этот код в Delphi

Ответы [ 4 ]

1 голос
/ 12 ноября 2009

(отредактировано в ответ на комментарии ниже.)

Для этого есть пара шагов: во-первых, на самом деле запустить скрипт; во-вторых, проверьте, успешно ли он запустился (как ему удалось запустить новый процесс, так и успешно ли этот процесс).

Часть 1, запуск сценария:

Чтобы запустить скрипт из приложения Delphi, используйте ShellExecuteEx с глаголом "open", который должен работать (подробнее см. Флаги ниже.) Вы можете выполнить сам скрипт, если он связан с исполняемый файл Perl или запустите исполняемый файл Perl со сценарием в качестве аргумента командной строки.

Эта статья выглядит хорошей отправной точкой для использования этого API и его более простого двоюродного брата ShellExecute.

Функции ShellExecute[Ex] обычно ожидают, что ваше приложение впоследствии запустит цикл обработки сообщений. Маловероятно, что ваше приложение не так, до тех пор, пока пользователь нажимает кнопку, чтобы запустить это приложение, оно бездействует, но если по какой-то причине это не происходит, вы должны пройти флаг SEE_MASK_NOASYNC. MSDN имеет много информации.

Часть 2, проверка, успешно ли он выполнен и успешно справился со своей задачей:

Чтобы увидеть, выполнен ли скрипт, вы должны получить дескриптор процесса для запущенного процесса и, если был новый процесс, проверить код выхода из этого. Вы должны изменить свой скрипт, чтобы он возвращал ненулевой код, если его задача не выполнена. (Я не знаком с Perl, поэтому не могу сказать, как именно, но обычно это возвращаемое значение из функции "main" или другой функции first / startup.) Вы можете сделать это с помощью:

  • Передайте флаг SEE_MASK_NOCLOSEPROCESS в ShellExecuteEx. Это заполнит hProcess член структуры, которую вы передаете, дескриптором процесса, если он успешно запустил процесс (если нет, проверьте GetLastError, чтобы выяснить, почему.) Если это все, что вам нужно знать (только если все началось, ничего, если это сработало) то все готово.
  • Необязательно: дождитесь завершения процесса, используя WaitForSingleObject(YourParamStruct.hProcess, INFINITE) (если, конечно, вы получили действительный hProcess)
  • Позвоните GetExitCodeProcess, чтобы найти код выхода. (Проверьте, что он возвращает STILL_ACTIVE, и, если он все еще работает, подождите и повторите попытку.) Как правило, он должен завершиться с 0, чтобы указать успех. Вы должны изменить ваш скрипт так, чтобы если что-то пошло не так, он возвращал ненулевое значение. Вы можете сделать коды такими же простыми или сложными, как хотите - например, вернуть 1 для любой ошибки или сделать несколько кодов, разбитых по типу ошибки. (Избегайте использования 259, потому что это значение STILL_ACTIVE - это может привести ваш Delphi-код в бесконечный цикл, в зависимости от того, как он закодирован, думая, что он все еще ожидает получения кода выхода, потому что сценарий Perl все еще выполняется, когда это не так.)

Ваше приложение Delphi может затем проверить этот код, чтобы увидеть, работает ли Perl-скрипт или нет, и сделать что-то в ответ в случае неудачи - зарегистрировать сообщение, сообщить пользователю и т. Д.

Еще одна вещь - вы говорите, что просто хотите знать, выполняется сценарий или нет, и вышеприведенное должно это обеспечить. Учитывая, что это сценарий Perl и выполняется в командной строке, вам может потребоваться еще одна вещь - получить его выходные данные, либо сканировать на наличие ошибок, если вы не возвращаете код ошибки, либо регистрировать или показывать пользователю. Вы можете сделать это, запустив его через CreateProcess и , захватив выходные данные . Из того, что вы говорите, это, вероятно, излишне для того, что вы после этого!

0 голосов
/ 12 ноября 2009

Если вы хотите ShellExecute() пакетный файл, вам нужно выполнить cmd.exe и передать скрипт в качестве параметра, например так:

ShellExecute(Handle, 'open', 'cmd.exe', '/C C:\loaderperl.bat', nil, SW_SHOW);

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

0 голосов
/ 12 ноября 2009

Вам необходимо вызвать внешнюю программу (интерпретатор perl для выполнения на локальном компьютере, ssh или smth для выполнения на удаленном компьютере). Вот процедура, которая вызывает внешнюю программу и ждет, пока она не закончится (если вам не нужно ждать, пока она не закончится, удалите WaitForSingleObject или просто вызовите ShellExecute, как предложили другие люди).

ОБНОВЛЕНИЕ: чтобы увидеть вывод скрипта, попробуйте использовать решение из этой статьи

function ExecAndWait(const FileName, Params: ShortString; const WinState: Word): boolean; export; 
var 
  StartInfo: TStartupInfo; 
  ProcInfo: TProcessInformation; 
  CmdLine: ShortString; 
begin 
  { Put the name of file between quotes, due to spaces in names of files in system Win9x } 
  CmdLine := '"' + Filename + '" ' + Params; 
  FillChar(StartInfo, SizeOf(StartInfo), #0); 
  with StartInfo do 
  begin 
    cb := SizeOf(SUInfo); 
    dwFlags := STARTF_USESHOWWINDOW; 
    wShowWindow := WinState; 
  end; 
  Result := CreateProcess(nil, PChar( String( CmdLine ) ), nil, nil, false, 
                          CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, 
                          PChar(ExtractFilePath(Filename)),StartInfo,ProcInfo);
  { Wait the finish of program } 
  if Result then 
  begin 
    WaitForSingleObject(ProcInfo.hProcess, INFINITE); 
    { Free the Handles } 
    CloseHandle(ProcInfo.hProcess); 
    CloseHandle(ProcInfo.hThread); 
  end; 
end; 
0 голосов
/ 12 ноября 2009

Запустить rsh или что-то еще в ваших окнах unix с соответствующими аргументами (интерпретатор perl + расположение скрипта + имя) с использованием shellexecute?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...