2009-11-12 1 views
3

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

Я попытался с помощью ShellExecute:

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

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

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

+0

Является ли это родным delphi или .NET? Что вы подразумеваете под окном unix? –

+0

Просьба уточнить, хотите ли вы выполнить это локально или на удаленной системе, и если локально какая среда (CygWin, MSys) или какая оболочка (sh, bash, rxvt, ...) вы хотите использовать. – mghie

+1

Дубликат http://stackoverflow.com/questions/1454501/how-do-i-run-a-command-line-program-in-delphi – mghie

ответ

0

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

1

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

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

Часть 1, выполнив сценарий:

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

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

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

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

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

  • Передать флаг 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 и capturing the output. Из того, что вы говорите, это, вероятно, слишком много для того, что вам нужно, хотя!

+0

Я всегда выполнял бы оболочку и передавал ей имя сценария в качестве параметра, позволяя использовать подстановочные знаки, перенаправление ввода/вывода и тому подобное. Строка shebang гарантирует, что перлов-интерпретатор будет запущен. – mghie

+0

Это никогда не приходило мне в голову, mghie - хороший момент! –

+0

Автоматизация означает, что человеческий перерыв должен быть равен нулю. При нажатии кнопки код должен автоматически запускать скрипт perl. Я попытался использовать ShellExecute: ShellExecute (Handle, 'open', Pchar ('C: \ loaderperl.bat'), nil, nil, SW_SHOW); Окно мигает на секунду и закрывается. Я не знаю, выполнялся ли скрипт или нет. Не могли бы вы, пожалуйста, очистить меня? – JVNR

0

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

UPDATE: Чтобы увидеть вывод скрипта, попробуйте использовать решение из this article

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

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

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

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