На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: jack128, Rouse_, Krid
  
    > Запуск программы с ожиданием её выполнения
      Запустить процесс и дождаться его завершения

      В приведённом ниже примере, не претендующем на панацею, используется запуск архиватора rar в отдельном процессе для архивирования/разархивирования целого каталога. После этого организуется цикл ожидания, до тех пор пока процесс не отработает. Обратите внимание, что используется альтернатива функции WaitForSingleObject(), собственная организация цикла. Хорошо это или плохо, решать вам.

      ExpandedWrap disabled
        Procedure CrProcess(FileName, S, Dir, WindowName: String);
        // © Song
        Var SeInfo: TShellExecuteInfo;
           ExitCode: DWord;
        Begin
         FillChar(SEInfo,SizeOf(SEInfo),0);
         With SEInfo Do
          Begin
           cbSize:=SizeOf(TShellExecuteInfo);
           fmask:=SEE_MASK_NOCLOSEPROCESS;
           Wnd:=Application.Handle;
           lpFile:=PChar('"'+FileName+'"');
           lpParameters:=PChar(S);
           lpDirectory:=nil;
            { Можете использовать другие константы, если хотите, чтобы выполнение процесса было видно }
           nShow:=SW_HIDE;
          End; {With}
         IF ShellExecuteEx(@SEInfo) then
          Repeat
           Application.ProcessMessages;
           GetExitCodeProcess(SEInfo.hProcess,ExitCode);
          Until(FindWindow(nil,PChar(WindowName))<>0) or
               (ExitCode<>STILL_ACTIVE) or Application.Terminated else MessageDlg('Ошибка создания внешнего процесса. Код ошибки: '+SysErrorMessage(GetLastError),mtError,[mbAbort],0);
         CloseHandle(SEInfo.hProcess);
         IF FindWindow(nil,PChar(WindowName))<>0 then
          Begin
           SendMessage(FindWindow(nil,PChar(WindowName)),WM_CLOSE,0,0);
           While FindWindow(nil,PChar(WindowName))<>0 Do Application.ProcessMessages;
          End; {IF}
        End;


      Примеры использования:

      ExpandedWrap disabled
        // заархиировать
        CrProcess('путь_к_архиваору_rar','a -r0 -m5 '+'имя_архива'+#32+'имя_каталога'+'*.*',TempPath,'(Сеанс завершен) - Rar');
         
        // разархивировать
        CrProcess('путь_к_архиваору_rar','x -y '+'имя_архива'+#32+'каталог_куда_разархивировать','(Сеанс завершен) - Rar');


      Процедура написана исходя из совместимости со старыми ДОС процессами. ДОС программы не оставляют код завершения своего процесса по коду STILL_ACTIVE, а поэтому в таком случае запуск процесса "повиснет", т.е. будет постоянно "крутится" в цикле Repeat .. Until(). Для таких случаев преднозначена переменная WindowName. Когда ДОС задача завершается, появляется окно "(Сеанс завершён)  - Имя_процесса". Используйте эту переменную, если вы запускаете ДОС программу, вписав при этом в эту переменную свою строку по аналогии. В этом случае цикл Repeat .. Until() оборвётся при наличии такого окна, т.е. когда процесс и завершится. До кучи ещё процедура закроет это окно, чтобы предотвратить проблему при многократных запусках.

      Вариант №2 через WaitForSingleObject

      Автор: Fabrнcio Fadel Kammer

      Пример показывает как из Вашей программы запустить внешнее приложение и подождать его завершения.

      ExpandedWrap disabled
        function ExecAndWait(const FileName, Params: ShortString; const WinState: Word): boolean; export;
        var
          StartInfo: TStartupInfo;
          ProcInfo: TProcessInformation;
          CmdLine: ShortString;
        begin
          { Помещаем имя файла между кавычками, с соблюдением всех пробелов в именах Win9x }
          CmdLine := '"' + Filename + '" ' + Params;
          FillChar(StartInfo, SizeOf(StartInfo), #0);
          with StartInfo do
          begin
            cb := SizeOf(StartInfo);
            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);
          { Ожидаем завершения приложения }
          if Result then
          begin
            WaitForSingleObject(ProcInfo.hProcess, INFINITE);
            { Free the Handles }
            CloseHandle(ProcInfo.hProcess);
            CloseHandle(ProcInfo.hThread);
          end;
        end;


      А вот пример вызова этой функции:

      ExpandedWrap disabled
        ExecAndWait( 'C:\windows\calc.exe', '', SH_SHOWNORMAL)


      Параметр FileName = Имя внешней программы.
      Параметр Params = Параметры, необходимые для запуска внешней программы
      Параметр WinState = Указывает - как будет показано окно:
      Для этого параметра мы можем так же использовать следующие константы:
      SW_HIDE, SW_MAXIMIZE, SW_MINIMIZE, SW_SHOWNORMAL

      PS: Этот код тестировался в delphi версий 3, 4 и 5.

      Тема - элемент ЧАВО. Подготовлена by © Song
      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script execution time: 0,0247 ]   [ 16 queries used ]   [ Generated: 27.04.24, 16:52 GMT ]