Pourquoi la méthode Exited de mon processus n'est-elle pas appelée?

96

J'ai le code suivant, mais pourquoi la ProcessExitedméthode n'est-elle jamais appelée? C'est la même chose si je n'utilise pas le shell Windows ( startInfo.UseShellExecute = false).

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
}
5 ans plus tardDBA
la source

Réponses:

241

Pour recevoir un rappel lors d'un Exitedévénement, le EnableRaisingEventsdoit être défini sur true.

Process correctionProcess = Process.Start(startInfo);
correctionProcess.EnableRaisingEvents = true;
correctionProcess.Exited += new EventHandler(ProcessExited); 
Élisée
la source
3
correctionProcess.WaitForExit (), sans cette fonction, ce code ne fonctionne pas pour moi
Kira
7
Un petit conseil (surtout pour les non-experts C #): ne faites pas Close()le processus! J'ai rencontré un problème intermittent avec le gestionnaire de sortie en raison d'un effort malavisé de gestion des ressources. Le code en question est appelé Process.Close()après Process.Start(startInfo), plutôt que de permettre au GC de le récupérer en temps voulu. Erreur facile si votre arrière-plan est des langages non GC (par exemple C / C ++).
Jerzy
3
Génial. Merci. Je tiens également à faire remarquer que l'affectation de EnableRaisingEventset EventHandlersdoit être effectuée exactement après le Process.Start(). Cela ne fonctionnera pas autrement.
Doruk
2
@Doruk Je peux définir EnableRaisingEvents=trueavant d'appeler Process.Start()et cela fonctionne bien.
Action Dan
29

Depuis MSDN :

L'événement Exited indique que le processus associé s'est terminé. Cette occurrence signifie que le processus s'est terminé (abandonné) ou s'est terminé avec succès. Cet événement ne peut se produire que si la valeur de la propriété EnableRaisingEvents est true.

Avez-vous défini cette propriété sur true?

CodageGorille
la source
19
C'est aussi un drapeau très peu idomatique (à quoi ça sert de toute façon, si je ne veux pas l'événement, je ne m'y abonne pas!)
Tamás Szelei
3
Pas très intuitif. Doit indiquer clairement dans chaque description d'événement que cet indicateur doit être défini.
TheLegendaryCopyCoder
18

Vous devez définir Process.EnableRaisingEventssur true.

Sam B
la source
13

Définissez correctionProcess.EnableRaisingEvents = true

Gary L Cox Jr
la source
9

J'ai rencontré des exemples qui figurent new Process()dans un usingarticle. Ne faites pas cela si vous souhaitez utiliser la Exitedfonction. leusing clause détruit l'instance avec tous les descripteurs d'événements surExited .

Ce...

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

Ça devrait être ça ...

var process = new Process();
Adam Cox
la source
J'ai remarqué cela aussi. Curieusement, les événements OutputDataReceived fonctionnent correctement. Ou peut-être qu'ils se produisent si rapidement que l'exécution dans le thread principal ne s'arrête pas à l'aide.
AlexVB