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
}

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); 

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?


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.



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();

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.