等待进程结束

245

我有一个应用程序

Process.Start()

我想启动另一个名为'ABC'的应用程序。 我希望等待该应用程序结束(进程死亡)后再继续执行。 我应该如何做?

可能会同时运行多个名为'ABC'的应用程序实例。


如果你想异步地完成它(即在完成后触发事件),你可以在 Stack Overflow 上查看这里 - Matt
9个回答

461

我认为你只是想要这个:

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

请查看MSDN页面,此页面涉及该方法。此外,它还有一个超载函数,您可以在其中指定超时时间,以免可能一直等待。


150

想要阻塞进程直到其退出,可以使用Process.WaitForExit 方法。如果不想阻塞,则可以订阅Process.Exited 事件?如果这些方法无法满足您的需求,请提供更多信息。


确实有关于 Process.Exited 的好信息,但是 OP 说过“等待”。 - Mike M
8
这就是为什么我首先提到了“WaitForExit”... 在某些情况下,当完成某些操作时可能需要执行更多的代码,但这并不意味着您需要阻塞当前线程。 - Jon Skeet
8
如果你要使用Process.Exited事件,我认为你必须事先配置进程,通过将Process.EnableRaisingEvents设置为true。尽管考虑到这个问题已经超过三年了,可能在提问时Process.EnableRaisingEvents还不存在。 - Will
我最终来到了这个页面,寻找“Process.Exited”事件的名称。谢谢!因为完整性而加一。 - Chad
1
(再过三年...)请注意,如果目标进程被提升权限,则设置Process.EnableRaisingEvents会抛出Win32Exception(访问被拒绝),并且HasExited也会引发相同的异常。 (至少在.NET Framework 4.8中仍然如此。) - skst

41

我在我的应用程序中执行以下操作:

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.

这里有一些额外的功能,你可能会发现它们有用...


23

您可以使用等待退出或者捕获HasExited属性并更新您的UI以保持用户"知情"(期望管理):

System.Diagnostics.Process process = System.Diagnostics.Process.Start("cmd.exe");
while (!process.HasExited)
{
    //update UI
}
//done

12

我曾遇到这样一种情况,即在关闭属于进程的窗口后,Process.HasExited 没有发生变化。因此,Process.WaitForExit() 也没有起作用。我不得不监控 Process.Responding,而在关闭窗口后它变为 false,像这样:

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

也许这能帮到某个人。


6

4

参考微软的示例:

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

最好的方法是设置:

myProcess.EnableRaisingEvents = true;

否则,代码将被阻止。同时不需要额外的属性。
// 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}");
}

2

就像Jon Skeet所说的那样,使用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);
}

并没有真正回答问题。请完善您的回答以解决问题。 - Grantly
现在呢?也许打开 VB 并制作解决方案吧 ;) - David Lopes

-5

试试这个:

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

6
评论已被回答的问题已经得到解答,这样做有何意义?你不仅浪费了自己的时间,还让我也浪费了我的时间。请不要这样做。 - MuffintopBikini
@AdamBilinski 的问题和答案旨在让其他有同样问题的人看到,而不仅仅是提问者。 - David Gomes
4
我同意,但这个答案和被采纳的答案完全一样,所以毫无意义! - Adam Bilinski
@AdamBilinski 哦,是的,我没有仔细阅读你的评论,请原谅我 xD - David Gomes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接