244

I've an application which does

Process.Start()

to start another application 'ABC'. I want to wait till that application ends (process dies) and continue my execution. How can I do it?

There may be multiple instances of the application 'ABC' running at the same time.

rory.ap
  • 34,009
  • 10
  • 83
  • 174
NLV
  • 21,141
  • 40
  • 118
  • 183
  • And if you want to do it asynchronously (i.e. raise an event after completion), you can [look here](https://stackoverflow.com/q/13685290/1016343) at SO. – Matt Apr 11 '18 at 15:09

9 Answers9

460

I think you just want this:

var process = Process.Start(...);
process.WaitForExit();

See the MSDN page for the method. It also has an overload where you can specify the timeout, so you're not potentially waiting forever.

Demodave
  • 6,242
  • 6
  • 43
  • 58
Noldorin
  • 144,213
  • 56
  • 264
  • 302
149

Use Process.WaitForExit? Or subscribe to the Process.Exited event if you don't want to block? If that doesn't do what you want, please give us more information about your requirements.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • definitely good info with Process.Exited, but the OP did say "wait" – Mike M Jun 25 '14 at 18:07
  • 8
    @MikeM: Which is why I referred to `WaitForExit` first... in some cases you may want to execute more code when something finishes, but that doesn't mean you need to block the current thread. – Jon Skeet Jun 25 '14 at 18:08
  • 8
    If you are going to use the `Process.Exited` event, I believe that you have to configure the process beforehand by setting `Process.EnableRaisingEvents` to true. Though, considering that this question is over three years old, it may be that `Process.EnableRaisingEvents` was not a thing at the time of it's having been asked. – Will May 28 '17 at 01:52
  • I wound up on this page looking for the name of the `Process.Exited` event. Thanks! +1 for completeness – Chad Sep 04 '18 at 02:23
  • 1
    (Three more years later...) Note that setting `Process.EnableRaisingEvents` throws a [`Win32Exception`](https://www.giorgi.dev/net/access-denied-process-bugs/) (Access Denied) (as does `HasExited`) if the target process is elevated. (At least it still does as of .NET Framework 4.8.) – skst Aug 28 '20 at 23:18
41

I do the following in my application:

Process process = new Process();
process.StartInfo.FileName = executable;
process.StartInfo.Arguments = arguments;
process.StartInfo.ErrorDialog = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
process.Start();
process.WaitForExit(1000 * 60 * 5);    // Wait up to five minutes.

There are a few extra features in there which you might find useful...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
AnthonyLambert
  • 8,768
  • 4
  • 37
  • 72
23

You could use wait for exit or you can catch the HasExited property and update your UI to keep the user "informed" (expectation management):

System.Diagnostics.Process process = System.Diagnostics.Process.Start("cmd.exe");
while (!process.HasExited)
{
    //update UI
}
//done
wonea
  • 4,783
  • 17
  • 86
  • 139
riffnl
  • 3,248
  • 1
  • 19
  • 32
12

I had a case where Process.HasExited didn't change after closing the window belonging to the process. So Process.WaitForExit() also didn't work. I had to monitor Process.Responding that went to false after closing the window like that:

while (!_process.HasExited && _process.Responding) {
  Thread.Sleep(100);
}
...

Perhaps this helps someone.

Buka
  • 226
  • 3
  • 12
6

Process.WaitForExit should be just what you're looking for I think.

Hans Olsson
  • 54,199
  • 15
  • 94
  • 116
4

Referring to the Microsoft example: [https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.enableraisingevents?view=netframework-4.8]

Best would be to set:

myProcess.EnableRaisingEvents = true;

otherwiese the Code will be blocked. Also no additional properties needed.

// Start a process and raise an event when done.
myProcess.StartInfo.FileName = fileName;
// Allows to raise event when the process is finished
myProcess.EnableRaisingEvents = true;
// Eventhandler wich fires when exited
myProcess.Exited += new EventHandler(myProcess_Exited);
// Starts the process
myProcess.Start();

// Handle Exited event and display process information.
private void myProcess_Exited(object sender, System.EventArgs e)
{
Console.WriteLine(
                  $"Exit time    : {myProcess.ExitTime}\n" +
                  $"Exit code    : {myProcess.ExitCode}\n" +
                  $"Elapsed time : {elapsedTime}");
}
Julian
  • 886
  • 10
  • 21
2

Like Jon Skeet says, use the Process.Exited:

proc.StartInfo.FileName = exportPath + @"\" + fileExe;
proc.Exited += new EventHandler(myProcess_Exited);
proc.Start();
inProcess = true;

while (inProcess)
{
    proc.Refresh();
    System.Threading.Thread.Sleep(10);
    if (proc.HasExited)
    {
        inProcess = false;
    }
}

private void myProcess_Exited(object sender, System.EventArgs e)
{
    inProcess = false;
    Console.WriteLine("Exit time:    {0}\r\n" +
      "Exit code:    {1}\r\n", proc.ExitTime, proc.ExitCode);
}
Manfred Radlwimmer
  • 13,257
  • 13
  • 53
  • 62
David Lopes
  • 520
  • 3
  • 10
-5

Try this:

string command = "...";
var process = Process.Start(command);
process.WaitForExit();
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 6
    What's the point commenting on an answer to an already answered question about the question already being answered? Not only have you wasted your own cycles but you've compelled me to waste mine too. – MuffintopBikini Jul 01 '15 at 13:53
  • @AdamBilinski questions and answers are intended to be seen by other people that have the question not only the one who asked – David Gomes Jul 23 '15 at 23:07
  • 4
    @L3n I agree, but this answer is exactly the same as the accepted answer so it's pointless! – Adam Bilinski Jul 24 '15 at 08:55
  • @AdamBilinski Oh yea didn't read your comment properly forgive me xD – David Gomes Jul 24 '15 at 15:21