[delphi] oczekiwanie na zakończenie procesu

0

Załóżmy że w swoim programie uruchamiam jakiś inny program.

Kolejne instrukcje powinny być wykonane dopiero po zakończeniu działania tamtego programu. Jak zrobić by na czas uruchomienia tamtego programu wykonanie mojego było wstrzymane?

0

Musisz zdobyć uchwyt procesu (na to są różne sposoby w zależnosci czy tamten program jest uruchamiany z poziomu Twojego programu, czy też jest to już działająca aplikacja okienkowa czy nie itd.) a do czekania na jego zakończenie możesz wykorzystać funkcję WaitForSingleObject

0

+wątki

0

W moim przypadku będzie to konsolowy 7-zip którego zadaniem będzie wypakowanie archiwum.

Skąd w takim przypadku pobrać uchwyt?

0

Jeżeli Ty uruchamiasz aplikację to zerknij na:
http://www.swissdelphicenter.ch/torry/showcode.php?id=93
nie testowałem ale powinno działać . Proponuję rozwiązania oparte na ShellExecuteEx

0

Ja w swoim programie odpalam wiele innych procesów z poziomu wiersza poleceń i sprawdzam czy zakończyły swoje działanie za pomocą czegoś takiego:

  procedure WaitFor(processHandle: THandle);
  var
    msg: TMsg;
    ret: DWORD;
  begin
    repeat
      ret := MsgWaitForMultipleObjects(1, processHandle, False, INFINITE, QS_PAINT or QS_SENDMESSAGE);
      if ret = WAIT_FAILED then Exit;
      if ret = (WAIT_OBJECT_0 + 1) then begin
        while PeekMessage(msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE) do begin
          DispatchMessage(msg);
        end;
      end;
    until ret = WAIT_OBJECT_0;
  end;
0

kAzek, dzięki za link.

Wykorzystałem taki kod

function ExecAndWait(FileName: string; Visibility: Integer): DWORD;
  procedure WaitFor(processHandle: THandle);
  var
    Msg: TMsg;
    ret: DWORD;
  begin
    repeat
      ret := MsgWaitForMultipleObjects(1, { 1 handle to wait on }
        processHandle, { the handle }
        False, { wake on any event }
        INFINITE, { wait without timeout }
        QS_PAINT or { wake on paint messages }
        QS_SENDMESSAGE { or messages from other threads }
        );
      if ret = WAIT_FAILED then Exit; { can do little here }
      if ret = (WAIT_OBJECT_0 + 1) then
      begin
          { Woke on a message, process paint messages only. Calling
            PeekMessage gets messages send from other threads processed. }
        while PeekMessage(Msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE) do
          DispatchMessage(Msg);
      end;
    until ret = WAIT_OBJECT_0;
  end; { Waitfor }
var { V1 by Pat Ritchey, V2 by P.Below }
  zAppName: array[0..512] of char;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin { WinExecAndWait32V2 }
  StrPCopy(zAppName, FileName);
  FillChar(StartupInfo, SizeOf(StartupInfo), #0);
  StartupInfo.cb          := SizeOf(StartupInfo);
  StartupInfo.dwFlags     := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := Visibility;
  if not CreateProcess(nil,
    zAppName, { pointer to command line string }
    nil, { pointer to process security attributes }
    nil, { pointer to thread security attributes }
    False, { handle inheritance flag }
    CREATE_NEW_CONSOLE or { creation flags }
    NORMAL_PRIORITY_CLASS,
    nil, { pointer to new environment block }
    nil, { pointer to current directory name }
    StartupInfo, { pointer to STARTUPINFO }
    ProcessInfo) { pointer to PROCESS_INF } then
    Result := DWORD(-1) { failed, GetLastError has error code }
  else
  begin
    Waitfor(ProcessInfo.hProcess);
    GetExitCodeProcess(ProcessInfo.hProcess, Result);
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
  end; { Else }
end; { WinExecAndWait32V2 }

Działa świetnie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1