221
votes

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.

9
And if you want to do it asynchronously (i.e. raise an event after completion), you can look here at SO. - Matt

9 Answers

427
votes

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.

140
votes

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.

38
votes

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...

19
votes

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
12
votes

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.

6
votes

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

3
votes

Referring to the Microsoft example: [https://docs.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}");
}
0
votes

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);
}
-5
votes

Try this:

string command = "...";
var process = Process.Start(command);
process.WaitForExit();