<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=40409&amp;view=findpost&amp;p=261983</guid>
        <pubDate>Fri, 12 Dec 2003 08:09:33 +0000</pubDate>
        <title>Запуск программы с ожиданием её выполнения</title>
        <link>https://forum.sources.ru/index.php?showtopic=40409&amp;view=findpost&amp;p=261983</link>
        <description><![CDATA[Song: <span class='tag-size' data-value='14' style='font-size:14pt;'>Запустить процесс и дождаться его завершения</span><br>
<br>
В приведённом ниже примере, не претендующем на панацею, используется запуск архиватора rar в отдельном процессе для архивирования/разархивирования целого каталога. После этого организуется цикл ожидания, до тех пор пока процесс не отработает. Обратите внимание, что используется альтернатива функции WaitForSingleObject(), собственная организация цикла. Хорошо это или плохо, решать вам.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Procedure CrProcess(FileName, S, Dir, WindowName: String);</div><div class="code_line">// © Song</div><div class="code_line">Var SeInfo: TShellExecuteInfo;</div><div class="code_line">&nbsp;  ExitCode: DWord;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;FillChar(SEInfo,SizeOf(SEInfo),0); </div><div class="code_line">&nbsp;With SEInfo Do</div><div class="code_line">&nbsp; Begin</div><div class="code_line">&nbsp;  cbSize:=SizeOf(TShellExecuteInfo);</div><div class="code_line">&nbsp;  fmask:=SEE_MASK_NOCLOSEPROCESS;</div><div class="code_line">&nbsp;  Wnd:=Application.Handle;</div><div class="code_line">&nbsp;  lpFile:=PChar(&#39;&quot;&#39;+FileName+&#39;&quot;&#39;);</div><div class="code_line">&nbsp;  lpParameters:=PChar(S);</div><div class="code_line">&nbsp;  lpDirectory:=nil;</div><div class="code_line">&nbsp;   { Можете использовать другие константы, если хотите, чтобы выполнение процесса было видно }</div><div class="code_line">&nbsp;  nShow:=SW_HIDE;</div><div class="code_line">&nbsp; End; {With}</div><div class="code_line">&nbsp;IF ShellExecuteEx(@SEInfo) then</div><div class="code_line">&nbsp; Repeat</div><div class="code_line">&nbsp;  Application.ProcessMessages;</div><div class="code_line">&nbsp;  GetExitCodeProcess(SEInfo.hProcess,ExitCode);</div><div class="code_line">&nbsp; Until(FindWindow(nil,PChar(WindowName))&#60;&#62;0) or</div><div class="code_line">&nbsp;      (ExitCode&#60;&#62;STILL_ACTIVE) or Application.Terminated else MessageDlg(&#39;Ошибка создания внешнего процесса. Код ошибки: &#39;+SysErrorMessage(GetLastError),mtError,[mbAbort],0);</div><div class="code_line">&nbsp;CloseHandle(SEInfo.hProcess);</div><div class="code_line">&nbsp;IF FindWindow(nil,PChar(WindowName))&#60;&#62;0 then</div><div class="code_line">&nbsp; Begin</div><div class="code_line">&nbsp;  SendMessage(FindWindow(nil,PChar(WindowName)),WM_CLOSE,0,0);</div><div class="code_line">&nbsp;  While FindWindow(nil,PChar(WindowName))&#60;&#62;0 Do Application.ProcessMessages;</div><div class="code_line">&nbsp; End; {IF}</div><div class="code_line">End;</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
Примеры использования:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// заархиировать</div><div class="code_line">CrProcess(&#39;путь_к_архиваору_rar&#39;,&#39;a -r0 -m5 &#39;+&#39;имя_архива&#39;+#32+&#39;имя_каталога&#39;+&#39;*.*&#39;,TempPath,&#39;(Сеанс завершен) - Rar&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">// разархивировать</div><div class="code_line">CrProcess(&#39;путь_к_архиваору_rar&#39;,&#39;x -y &#39;+&#39;имя_архива&#39;+#32+&#39;каталог_куда_разархивировать&#39;,&#39;(Сеанс завершен) - Rar&#39;);</div></ol></div></div></div></div><br>
<br>
Процедура написана исходя из совместимости со старыми ДОС процессами. ДОС программы не оставляют код завершения своего процесса по коду STILL_ACTIVE, а поэтому в таком случае запуск процесса &quot;повиснет&quot;, т.е. будет постоянно &quot;крутится&quot; в цикле Repeat .. Until(). Для таких случаев преднозначена переменная WindowName. Когда ДОС задача завершается, появляется окно &quot;(Сеанс завершён)  - Имя_процесса&quot;. Используйте эту переменную, если вы запускаете ДОС программу, вписав при этом в эту переменную свою строку по аналогии. В этом случае цикл Repeat .. Until() оборвётся при наличии такого окна, т.е. когда процесс и завершится. До кучи ещё процедура закроет это окно, чтобы предотвратить проблему при многократных запусках.<br>
<br>
<span class='tag-size' data-value='14' style='font-size:14pt;'>Вариант №2 через WaitForSingleObject</span><br>
<br>
Автор: Fabrнcio Fadel Kammer<br>
<br>
Пример показывает как из Вашей программы запустить внешнее приложение и подождать его завершения.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function ExecAndWait(const FileName, Params: ShortString; const WinState: Word): boolean; export; </div><div class="code_line">var </div><div class="code_line">&nbsp; StartInfo: TStartupInfo; </div><div class="code_line">&nbsp; ProcInfo: TProcessInformation; </div><div class="code_line">&nbsp; CmdLine: ShortString; </div><div class="code_line">begin </div><div class="code_line">&nbsp; { Помещаем имя файла между кавычками, с соблюдением всех пробелов в именах Win9x } </div><div class="code_line">&nbsp; CmdLine := &#39;&quot;&#39; + Filename + &#39;&quot; &#39; + Params; </div><div class="code_line">&nbsp; FillChar(StartInfo, SizeOf(StartInfo), #0); </div><div class="code_line">&nbsp; with StartInfo do </div><div class="code_line">&nbsp; begin </div><div class="code_line">&nbsp;   cb := SizeOf(StartInfo); </div><div class="code_line">&nbsp;   dwFlags := STARTF_USESHOWWINDOW; </div><div class="code_line">&nbsp;   wShowWindow := WinState; </div><div class="code_line">&nbsp; end; </div><div class="code_line">&nbsp; Result := CreateProcess(nil, PChar( String( CmdLine ) ), nil, nil, false, </div><div class="code_line">&nbsp;                         CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, </div><div class="code_line">&nbsp;                         PChar(ExtractFilePath(Filename)),StartInfo,ProcInfo); </div><div class="code_line">&nbsp; { Ожидаем завершения приложения } </div><div class="code_line">&nbsp; if Result then </div><div class="code_line">&nbsp; begin </div><div class="code_line">&nbsp;   WaitForSingleObject(ProcInfo.hProcess, INFINITE); </div><div class="code_line">&nbsp;   { Free the Handles } </div><div class="code_line">&nbsp;   CloseHandle(ProcInfo.hProcess); </div><div class="code_line">&nbsp;   CloseHandle(ProcInfo.hThread); </div><div class="code_line">&nbsp; end; </div><div class="code_line">end; </div></ol></div></div></div></div><br>
<br>
А вот пример вызова этой функции:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">ExecAndWait( &#39;C:\windows\calc.exe&#39;, &#39;&#39;, SH_SHOWNORMAL) </div></ol></div></div></div></div><br>
<br>
Параметр FileName = Имя внешней программы. <br>
Параметр Params = Параметры, необходимые для запуска внешней программы<br>
Параметр WinState = Указывает - как будет показано окно:<br>
                Для этого параметра мы можем так же использовать следующие константы: <br>
                SW_HIDE, SW_MAXIMIZE, SW_MINIMIZE, SW_SHOWNORMAL <br>
<br>
PS: Этот код тестировался в delphi версий 3, 4 и 5.<br>
<br>
<span class="tag-color tag-color-named" data-value="green" style="color: green"><span class="tag-font" data-value="Arial" style="font-family:Arial"><span class='tag-size' data-value='8' style='font-size:8pt;'>Тема - элемент ЧАВО. Подготовлена by © Song</span></span></span>]]></description>
        <author>Song</author>
        <category>Системные функции, WinAPI, работа с железом</category>
      </item>
	
      </channel>
      </rss>
	