This Might Be Useful

Запуск приложения и ожидание его завершения

Некоторое время назад мне понадобилось сделать утилиту (launcher), которая бы делала некие действия, затем запускала определенную программу, ждала ее завершения, и снова делала определенные действия. Проблема, собственно, была в ожидании завершения. Все рецепты, найденные в Сети, пожирали 100% CPU time. Эта ситуация меня не устраивала, поэтому было найдено другое решение.

Для запуска необходимо подключить соответствующую библиотеку:

DELPHI:
  1. uses ShellApi;

Затем добавим в определение формы одну private-переменную:

DELPHI:
  1. SEInfo: TShellExecuteInfo;

Теперь в нужном месте программы запускаем приложение. У меня это происходило прямо на FormCreate.

DELPHI:
  1. procedure TLaunchForm.FormCreate(Sender: TObject);
  2. Var ExecuteFile, ParamString, StartInString: String;
  3. Begin
  4.   ...
  5.   ExecuteFile := 'полный_путь_и_имя_exe_файла';
  6.   ParamString := 'параметры_запуска';
  7.   StartInString := 'где_стартовать';
  8.  
  9.   FillChar(SEInfo, SizeOf(SEInfo), 0);
  10.   SEInfo.cbSize := SizeOf(TShellExecuteInfo);
  11.   with SEInfo do begin
  12.     fMask := SEE_MASK_NOCLOSEPROCESS;
  13.     Wnd := Application.Handle;
  14.     lpFile := PChar(ExecuteFile);
  15.     lpParameters := PChar(ParamString);
  16.     lpDirectory := PChar(StartInString);
  17.     nShow := SW_SHOWNORMAL;
  18.   end;
  19.   if ShellExecuteEx(@SEInfo) then
  20.   begin
  21.     // тут можем сообщить, что программа запустилась
  22.   end
  23.   else
  24.   begin
  25.     // а тут можно ругаться, что приложение не запустилось
  26.   end;
  27.   ...
  28. End;

Если программа успешно запустилась, нам надо ждать ее завершения. Для этого кидаем на форму TApplicationEvents:

DELPHI:
  1. ApplicationEvents: TApplicationEvents;

Все проверки будем делать на событии OnIdle. Это избавит от использования лишних системных ресурсов.

DELPHI:
  1. procedure TLaunchForm.ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
  2. var ExitCode: DWord;
  3. begin
  4.   Application.ProcessMessages;
  5.   GetExitCodeProcess(SEInfo.hProcess, ExitCode);
  6.   If (ExitCode <> STILL_ACTIVE) or Application.Terminated Then
  7.   begin
  8.     // запущенное приложение завершилось
  9.   end;
  10. end;

Вот, собственно, и все. Единственный минус такого подхода - мы не всегда сразу реагируем на закрытие приложения, ведь мы ждем, пока Windows дернет веревочку onIdle. Но обычно это не столь критично, ибо опрос приложений происходит достаточно часто.

Для красоты я засунул программу в system tray. Как это сделать, описано тут.

· Установка иконки приложения в system tray
· Как ждать меньше на Depositfiles
· Горячие клавиши для Windows Vista, Internet Explorer, Windows Mail
· Улучшаем семантику ссылок
· Отдаем pdf-файл браузеру. Да так, чтобы MSIE его тоже принимал.

- Коментировать
- Trackback

One Response to “Запуск приложения и ожидание его завершения”


  1. Beavis Says:

    И опять чайники хором кричат тебе спасибо

Leave a Reply