2016-06-24 15 views
1

Ich versuche festzustellen, ob ein Prozess noch am Leben ist (im Moment habe ich überprüft, ich weiß, dass es direkt nach der Überprüfung geschlossen werden kann) WaitForSingleObject() mit einem Handle von Process.MainWindowHandle aufrufen das funktioniert gut mit IsIconic() aber es zurückgeben WAIT_FAILED und GetLastError() ein ERROR_INVALID_HANDLEWaitForSingleObject Rückgabe ERROR_INVALID_HANDLE

UInt32 r = WaitForSingleObject(handle, 0); 
if(r == WAIT_OBJECT_0) 
{ 
    MessageBox.Show("still running!"); 
} 
if(r == WAIT_FAILED) 
{ 
    throw new Win32Exception(Marshal.GetLastWin32Error()); 
} 
+0

Mögliches Duplikat von [Calling WaitForSingleObject aus C#] (http://StackOverflow.com/questions/33718217/calling-waitforsingleobject-from-c-sharp) – MethodMan

+1

Sie können nicht auf einen Fenstergriff warten. Überprüfen Sie die Dokumente unter https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032.aspx für die Arten von Handles, auf die gewartet werden kann. – dxiv

+0

Das System sagt, dass Ihr Handle nicht gültig ist. Ihr Handle ist nicht gültig. –

Antwort

5

Sie können nicht auf einem Fenstergriff warten. Sie können Fenster-Handles an fensterbezogene Funktionen übergeben, wie IsIconic(), aber sie sind keine Kernel-Objekte, Sie können also nicht darauf warten. The documentation gibt eine Liste von Objekten, die Sie auf warten können:

Die WaitForSingleObject Funktion für folgende Objekte warten können:

  • Änderungsmeldung
  • Console Eingang
  • Ereignis
  • Speicherressource Benachrichtigung
  • Mutex
  • Prozess
  • Semaphore
  • Thema
  • wartbar Timer

Also, wenn Sie auf einen Prozess warten soll, bis er endet, Sie auf den Griff des Prozesses warten kann, die über die zugänglich ist Process.Handle Eigentum.

Aber Sie müssen nicht tatsächlich P/Invoke die Win32-Funktion überhaupt. Die Wrapper-Klasse .NET Process verfügt über die Memberfunktionen WaitForExit() und WaitForInputIdle(), die zum Warten auf einen Prozess verwendet werden können (beachten Sie, dass beide Überladungen einen Timeout-Wert haben).

Wenn dies ein Prozess ist, den Sie mit der Process Klasse Wrapper gestartet haben, können Sie einfach die Process.HasExited Eigenschaft abfragen.

+2

Wenn Sie ein 'Process'-Objekt haben, sollten Sie' HasExited' nicht verwenden können, unabhängig davon, ob Sie derjenige waren, der den Prozess tatsächlich erzeugt hat? Ich sehe nicht, warum es sich kümmern sollte, wenn der Anrufer auch der Spawner ist. –

+0

danke für deine antwort, ich will nicht warten bis es austritt, habe den prozess auch nicht gestartet. Ich möchte überprüfen, ob ein bestimmter Prozess noch zu einer bestimmten Zeit noch aktiv ist (es passiert alle x Sekunden) – Jack

+0

@remy Der Grund, warum ich das geschrieben habe, ist, dass ich irgendwo gelesen habe, dass das nicht funktioniert hat. Vermutlich verfolgt die Process-Klasse diese Informationen nicht, es sei denn, sie startet den Prozess. Um mein Gedächtnis zu bestätigen, habe ich [diesen How-to-Artikel] (https://msdn.microsoft.com/en-us/library/y111seb2.aspx) gefunden, der ganz oben steht: * "Hinweis: Dieser Wert ist wird nur für Prozesse zurückgegeben, die von einer Process-Komponente gestartet werden. "* Dies ist möglicherweise nicht ganz richtig. Sie müssen die Referenzquelle überprüfen, um absolut sicher zu sein. –