C# – 创build一个Process.Start等到进程启动

在继续使用方法之前,我需要确保一个进程正在运行。

声明是:

Process.Start("popup.exe"); 

你可以做一个等待命令或设置延迟这个值?

你的意思是等到完成了吗? 然后使用Process.WaitForExit

 var process = new Process { StartInfo = new ProcessStartInfo { FileName = "popup.exe" } }; process.Start(); process.WaitForExit(); 

另外,如果它是一个用户界面的应用程序,你正在等待进入消息循环,你可以说:

 process.Start(); process.WaitForInputIdle(); 

最后,如果这些都不适用,只要Thread.Sleep一段合理的时间:

 process.Start(); Thread.Sleep(1000); // sleep for one second 

我也需要这一次,我做了一个检查过程的窗口标题。 如果是你期望的那个,你可以确定应用程序正在运行。 我正在检查的应用程序需要一些时间来启动,这种方法对我来说工作得很好。

 var process = Process.Start("popup.exe"); while(process.MainWindowTitle != "Title") { Thread.Sleep(10); } 

就像其他人已经说过的那样,你所问的并不是很明显。 我假定你想要启动一个进程,然后在进程“准备就绪”时执行另一个动作。

当然,“准备好”是棘手的问题。 根据你的需求,你可能会发现只需等待就足够了。 但是,如果您需要更强大的解决scheme,则可以考虑使用命名的Mutex来控制两个进程之间的控制stream。

例如,在你的主进程中,你可能会创build一个有名的互斥锁,并启动一个等待的线程或任务。 然后,你可以开始第二个过程。 当进程决定“准备就绪”时,它可以打开指定的互斥锁(当然,你必须使用相同的名称)并向第一个进程发送信号。

“ChrisG”的答案是正确的,但是我们每次都需要刷新MainWindowTitle,最好检查一下空白的….比如:

 var proc = Process.Start("popup.exe"); while (string.IsNullOrEmpty(proc.MainWindowTitle)) { System.Threading.Thread.Sleep(100); proc.Refresh(); } 

我同意汤姆。 另外,要在执行Thread.Sleep时检查进程,请检查正在运行的进程。 就像是:

 bool found = 0; while (!found) { foreach (Process clsProcess in Process.GetProcesses()) if (clsProcess.Name == Name) found = true; Thread.CurrentThread.Sleep(1000); } 

你确定Start方法在subprocess启动之前返回吗? 我总是觉得Start同步启动subprocess。

如果要等到subprocess完成某种初始化,则需要进程间通信 – 请参阅C#(.NET 2.0)中Windows的进程间通信

首先:我知道这个比较老,但是还没有被接受的答案,所以也许我的方法会帮助别人。 🙂

我做了什么来解决这个问题是:

 process.Start(); while (true) { try { var time = process.StartTime; break; } catch (Exception) {} } 

只要进程没有启动,关联var time = process.StartTime就会抛出一个exception。 所以一旦通过,就可以安全地假定进程正在运行,并进一步处理它。 我正在使用这个等待java进程启动,因为它需要一些时间。 这样,它应该独立于运行应用程序的机器而不是使用Thread.Sleep()

我明白这不是很干净的解决scheme,但唯一应该是性能独立,我能想到的。

为了扩展@ ChrisG的想法,请考虑使用process.MainWindowHandle并查看窗口消息循环是否响应。 使用p /调用这个Win32 API: SendMessageTimeout 。 从那个链接:

如果函数成功,返回值是非零的。 如果使用HWND_BROADCAST,则SendMessageTimeout不提供有关单个窗口超时的信息。

如果函数失败或超时,则返回值为0.要获得扩展的错误信息,请调用GetLastError。 如果GetLastError返回ERROR_TIMEOUT,则该函数超时。

我认为OP可能指的是需要从subprocess获得一个有效的窗口句柄,以便他能以某种方式处理它。

在我的情况下,我想产生一个Perl脚本在DOS控制台窗口中运行,并在窗体应用程序启动时居中窗口。 如果我抓取Process.MainWindowHandle太早,并调用“MoveWindow”,该句柄是无效的,并且该调用什么都不做。 如果等待一秒钟(通过调用Thread.Wait(1000)),屏幕将显示在其默认位置,并在一秒钟后突然移动。 要么对用户来说很烦人。

通过进入一个循环并等待“Process.MainWindowTitle”返回一些有意义的内容,我可以在窗口响应的时候立即抓住窗口,并将它置于窗体中,而不会产生烦人的闪烁。

OP可能正在尝试做类似的事情。