Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   WaitForSingleObject und Child-Prozesse (https://www.delphipraxis.net/162909-waitforsingleobject-und-child-prozesse.html)

nru 9. Sep 2011 09:42

WaitForSingleObject und Child-Prozesse
 
Hallo Ihr,

ich hab das Problem, dass das Ende einer über CreateProcess gestarteten InstallShield-Installation nicht über WaitForSingleObject abgefragt werden kann. Das gestartete (und eigentlich zu überwachende) setup.exe startet seinerseits einen Prozess und wird danach direkt beendet. :( Somit ist aus Sicht von WaitForSingleObject der gestartete und zu beobachtende Prozess beendet - aber nicht jedoch die eigentliche Installation.

Gibt es eine Möglichkeit auch auf das Ende des von setup.exe gestarteten Prozesses zu warten bzw. das zu prüfen?


Gruss
nru

Christian Seehase 9. Sep 2011 20:09

AW: WaitForSingleObject und Child-Prozesse
 
Moin nru,

meiner Erfahrung nach hat der von einem InstallShield so erzeugte neu erzeugte Prozess immer den gleichen Namen (ggf. ändert sich dieser nur in Abhängigkeit des Programmes, dass installiert werden soll).
Du könntest also mit CreateToolhelp32Snapshot überwachen, ob der abgespaltene Prozess existiert.

himitsu 9. Sep 2011 21:26

AW: WaitForSingleObject und Child-Prozesse
 
Man könnte auch versuchen die Erstellungsfunktion für den Subprozess zu hooken und würde somit an das gewünschte Prozesshandle bekommen.

Aber bei einem Setup könnte es schwierig werden, wenn dieses mit Adminrechten startet und der eigene Prozess keine besitzt.

Fridolin Walther 9. Sep 2011 22:06

AW: WaitForSingleObject und Child-Prozesse
 
Wenns ohne Code Injection oder Treiber gehen soll:
  1. Erstell den Prozess für Dein Setup, allerdings "suspended".
  2. Geh die Prozess Liste durch und schau nach Prozessen bei denen die Parent Process ID der Deines Setup Prozesses entspricht.
  3. Resume den Setup Prozess und warte auf dessen Ende.
  4. Bevor Du das Process Handle zu Deinem Setup Prozess schließt, generier erneut eine Prozess Liste und schau erneut nach Prozessen bei denen die Parent Process ID der Deines Setup Prozesses entspricht.
  5. Dann vergleich die Resultate der beiden Suchdurchläufe. Sobald ein Prozess beim zweiten Suchlauf gefunden wurde, beim ersten allerdings nicht, wurde dieser von Deinem Setup gestartet. Für jeden dieser Prozesse kannst Du Dir dann ein Prozess Handle holen und mit der WaitForMultipleObjects Funktion warten bis alle von Deinem Setup gestarteten Prozesse beendet wurden.
  6. Mach die ganzen Process Handles zu.
Klingt wahrscheinlich unglaublich kompliziert, ist im Endeffekt aber recht simpel.

QuickAndDirty 9. Sep 2011 23:38

AW: WaitForSingleObject und Child-Prozesse
 
Ich weiß nicht...laut MSDN funktioniert WaitForSingleObject nicht wenn weitere fenster aus dem prozess
heraus entstehen...

Sprich ich hatte so ein ähnliches Problem hier
http://www.delphipraxis.net/162142-t...cute-wait.html
Die Lösung war damals WaitForMultipleObjects
Delphi-Quellcode:
function ExecAndWait(Filename, Params: string; WindowState: word = SW_SHOWNORMAL): boolean;
var
  ShExecInfo: SHELLEXECUTEINFO;
  r : Cardinal;
  const
  SEE_MASK_NOASYNC= $100;
begin
  Result := false;
  if Filename = '' then
    exit;
  if not FileExists(FileName) then
  Begin
    ShowMessage('Datei nicht existent!');
    Exit;
  End;
  ZeroMemory(@ShExecInfo, SizeOf(ShExecInfo));
  ShExecInfo.Wnd := application.MainFormHandle; //GetForegroundWindow;
  ShExecInfo.cbSize := sizeof(SHELLEXECUTEINFO);
  ShExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_NOASYNC;
  ShExecInfo.lpVerb := 'open';
  ShExecInfo.lpFile := PChar(Filename);
  ShExecInfo.lpParameters := PChar(Params);
  ShExecInfo.lpDirectory := PChar(ExtractFileDir(Filename));
  ShExecInfo.nShow := WindowState;
  Result := ShellExecuteEx(@ShExecInfo);


  try
    if Result then
    begin
      repeat
        R := MsgWaitForMultipleObjects(1, ShExecInfo.hProcess, False, INFINITE,QS_ALLINPUT);
        if r <> WAIT_OBJECT_0 then
          Application.ProcessMessages;
      until r = WAIT_OBJECT_0;
    end
    else
      Showmessage('Fehler beim Starten der Anwendung:' + Filename +
                   #13#10'System Fehler: ' + SysErrorMessage(GetLastError));
  finally
    CloseHandle(ShExecInfo.hProcess);
  end;
end;

nru 12. Sep 2011 08:31

AW: WaitForSingleObject und Child-Prozesse
 
Vielen Dank für Eure wirklich guten Antworten. :thumb:
Hab mich letztlich für QuickAndDirty's Lösungsansatz entschieden, der sehr gut funktioniert.


Gruss
nru


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:57 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz