Запуск приложения и ожидание его завершения
Некоторое время назад мне понадобилось сделать утилиту (launcher), которая бы делала некие действия, затем запускала определенную программу, ждала ее завершения, и снова делала определенные действия. Проблема, собственно, была в ожидании завершения. Все рецепты, найденные в Сети, пожирали 100% CPU time. Эта ситуация меня не устраивала, поэтому было найдено другое решение.
Для запуска необходимо подключить соответствующую библиотеку:
-
uses ShellApi;
Затем добавим в определение формы одну private-переменную:
-
SEInfo: TShellExecuteInfo;
Теперь в нужном месте программы запускаем приложение. У меня это происходило прямо на FormCreate.
-
procedure TLaunchForm.FormCreate(Sender: TObject);
-
Var ExecuteFile, ParamString, StartInString: String;
-
Begin
-
...
-
ExecuteFile := 'полный_путь_и_имя_exe_файла';
-
ParamString := 'параметры_запуска';
-
StartInString := 'где_стартовать';
-
-
FillChar(SEInfo, SizeOf(SEInfo), 0);
-
SEInfo.cbSize := SizeOf(TShellExecuteInfo);
-
with SEInfo do begin
-
fMask := SEE_MASK_NOCLOSEPROCESS;
-
Wnd := Application.Handle;
-
lpFile := PChar(ExecuteFile);
-
lpParameters := PChar(ParamString);
-
lpDirectory := PChar(StartInString);
-
nShow := SW_SHOWNORMAL;
-
end;
-
if ShellExecuteEx(@SEInfo) then
-
begin
-
// тут можем сообщить, что программа запустилась
-
end
-
else
-
begin
-
// а тут можно ругаться, что приложение не запустилось
-
end;
-
...
-
End;
Если программа успешно запустилась, нам надо ждать ее завершения. Для этого кидаем на форму TApplicationEvents:
-
ApplicationEvents: TApplicationEvents;
Все проверки будем делать на событии OnIdle. Это избавит от использования лишних системных ресурсов.
-
procedure TLaunchForm.ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
-
var ExitCode: DWord;
-
begin
-
Application.ProcessMessages;
-
GetExitCodeProcess(SEInfo.hProcess, ExitCode);
-
If (ExitCode <> STILL_ACTIVE) or Application.Terminated Then
-
begin
-
// запущенное приложение завершилось
-
end;
-
end;
Вот, собственно, и все. Единственный минус такого подхода - мы не всегда сразу реагируем на закрытие приложения, ведь мы ждем, пока Windows дернет веревочку onIdle. Но обычно это не столь критично, ибо опрос приложений происходит достаточно часто.
Для красоты я засунул программу в system tray. Как это сделать, описано тут.


April 4th, 2008 at 16:09 Quote
И опять чайники хором кричат тебе спасибо