109

I have following code, but why is the ProcessExited method never called? It is the same if I don't a use Windows shell (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
}
River
  • 8,585
  • 14
  • 54
  • 67
5YrsLaterDBA
  • 33,370
  • 43
  • 136
  • 210

5 Answers5

281

In order to receive a callback on Exited event, the EnableRaisingEvents must be set to true.

Process correctionProcess = Process.Start(startInfo);
correctionProcess.EnableRaisingEvents = true;
correctionProcess.Exited += new EventHandler(ProcessExited); 
Elisha
  • 23,310
  • 6
  • 60
  • 75
  • 4
    correctionProcess.WaitForExit(), without this function this code is not working for me – Kira Jan 23 '16 at 14:43
  • 7
    One small tip (esp for non C# experts): don't `Close()` the process! I've encountered intermittent issue with the Exit handler due to a misguided effort at resource management. The code in question called `Process.Close()` after `Process.Start(startInfo)`, rather than allowing the GC to collect it in due course. Easy mistake if your background is non-GC languages (e.g. C/C++). – Jerzy Apr 01 '16 at 07:21
  • 3
    Great. Thanks. I also want to remark that assignment of `EnableRaisingEvents` and `EventHandlers` must be done exactly after the `Process.Start()`. It wont work otherwise. – Doruk Sep 21 '16 at 07:19
  • 2
    @Doruk I can set `EnableRaisingEvents=true` before calling `Process.Start()` and it works fine. – Action Dan Jun 15 '17 at 04:43
34

From MSDN:

The Exited event indicates that the associated process exited. This occurrence means either that the process terminated (aborted) or successfully closed. This event can occur only if the value of the EnableRaisingEvents property is true.

Have you set that property to true?

CodingGorilla
  • 19,612
  • 4
  • 45
  • 65
  • 27
    It is a very un-idomatic flag, too (what's the use anyway, if I don't want the event, I don't subscribe to it!) – Tamás Szelei Nov 03 '14 at 16:07
  • 4
    Not very intuitive. Should clearly state in each event description that it requires this flag to be set. – TheLegendaryCopyCoder Jan 31 '17 at 12:24
  • It's indeed not very intuitive but the property needs to be set so that the application can register to be notified about the target process' exit through the Win32 Api. – Laurent Jun 05 '23 at 09:42
21

You must set Process.EnableRaisingEvents to true.

Sam B
  • 2,441
  • 2
  • 18
  • 20
21

Set correctionProcess.EnableRaisingEvents = true

Gary L Cox Jr
  • 680
  • 3
  • 10
19

I've come across examples that place new Process() in a using clause. Do not do that if you want to use the Exited feature. The using clause destroys the instance along with any event handles on Exited.

This...

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

Should be this...

var process = new Process();
Adam Cox
  • 3,341
  • 1
  • 36
  • 46
  • I've noticed that too. Strangely enough, OutputDataReceived events work fine. Or may be they occur so fast that go before execution in the main thread comes to End Using. – AlexVB Aug 08 '19 at 18:12