Warum wird die Exited-Methode meines Prozesses nicht aufgerufen?

96

Ich habe folgenden Code, aber warum wird die ProcessExitedMethode nie aufgerufen? Es ist das gleiche, wenn ich keine Windows-Shell ( startInfo.UseShellExecute = false) verwende.

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = path;
startInfo.Arguments = rawDataFileName;
startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);

try
{
     Process correctionProcess = Process.Start(startInfo);
     correctionProcess.Exited += new EventHandler(ProcessExited);                   

     correctionProcess.WaitForExit();

     status = true;
}

..... .....

internal void ProcessExited(object sender, System.EventArgs e)
{
      //print out here
}
5YrsLaterDBA
quelle

Antworten:

241

Um einen Rückruf bei einem ExitedEreignis zu erhalten, EnableRaisingEventsmuss der Wert auf true gesetzt werden.

Process correctionProcess = Process.Start(startInfo);
correctionProcess.EnableRaisingEvents = true;
correctionProcess.Exited += new EventHandler(ProcessExited); 
Elisha
quelle
3
KorrekturProzess.WaitForExit (), ohne diese Funktion funktioniert dieser Code nicht für mich
Kira
7
Ein kleiner Tipp (besonders für Nicht-C # -Experten): Machen Sie Close()den Prozess nicht! Ich habe zeitweise Probleme mit dem Exit-Handler festgestellt, weil die Ressourcenverwaltung fehlgeleitet wurde. Der Code in Frage gestellt Process.Close()nach Process.Start(startInfo), statt zuzulassen , dass die GC es zu gegebener Zeit zu sammeln. Leichter Fehler, wenn Ihr Hintergrund keine GC-Sprachen sind (z. B. C / C ++).
Jerzy
3
Toll. Vielen Dank. Ich möchte auch darauf hinweisen, dass die Zuordnung von EnableRaisingEventsund EventHandlersgenau nach dem erfolgen muss Process.Start(). Sonst funktioniert es nicht.
Doruk
2
@ Doruk kann ich EnableRaisingEvents=truevor dem Anruf einstellen Process.Start()und es funktioniert gut.
Aktion Dan
29

Von MSDN :

Das Ereignis Beendet zeigt an, dass der zugeordnete Prozess beendet wurde. Dieses Vorkommen bedeutet entweder, dass der Prozess beendet (abgebrochen) oder erfolgreich abgeschlossen wurde. Dieses Ereignis kann nur auftreten, wenn der Wert der EnableRaisingEvents-Eigenschaft true ist.

Haben Sie diese Eigenschaft auf true gesetzt?

CodingGorilla
quelle
19
Es ist auch eine sehr unidomatische Flagge (was nützt es überhaupt, wenn ich das Ereignis nicht will, abonniere ich es nicht!)
Tamás Szelei
3
Nicht sehr intuitiv. Sollte in jeder Ereignisbeschreibung klar angeben, dass dieses Flag gesetzt sein muss.
TheLegendaryCopyCoder
18

Sie müssen festlegen Process.EnableRaisingEventszu true.

Sam B.
quelle
13

Setzen SierectionProcess.EnableRaisingEvents = true

Gary L Cox Jr.
quelle
9

Ich bin auf Beispiele gestoßen, die new Process()in einer usingKlausel stehen. Tun Sie das nicht, wenn Sie die Funktion verwenden möchten Exited. Die usingKlausel zerstört die Instanz zusammen mit allen EreignishandlesExited .

Dies...

using(var process = new Process())
{
   // your logic here
}

Sollte das sein ...

var process = new Process();
Adam Cox
quelle
Das habe ich auch bemerkt. Seltsamerweise funktionieren OutputDataReceived-Ereignisse einwandfrei. Oder sie treten so schnell auf, dass die Ausführung im Hauptthread zu Ende geht.
AlexVB