在继续使用方法之前,我需要确保进程正在运行。
陈述是:
Process.Start("popup.exe");
您可以执行WAIT命令或设置此值的延迟吗?
答案 0 :(得分:118)
你的意思是等到它完成了吗?然后使用Process.WaitForExit
:
var process = new Process {
StartInfo = new ProcessStartInfo {
FileName = "popup.exe"
}
};
process.Start();
process.WaitForExit();
或者,如果它是一个带有您正在等待进入消息循环的UI的应用程序,您可以说:
process.Start();
process.WaitForInputIdle();
最后,如果这些都不适用,只需Thread.Sleep
一段合理的时间:
process.Start();
Thread.Sleep(1000); // sleep for one second
答案 1 :(得分:14)
我也需要这个,我检查过程的窗口标题。如果它是您期望的那个,您可以确定应用程序正在运行。我正在检查的应用程序需要一些时间来启动,这种方法对我来说很好。
var process = Process.Start("popup.exe");
while(process.MainWindowTitle != "Title")
{
Thread.Sleep(10);
}
答案 2 :(得分:11)
ChrisG'的回答是正确的,但我们每次都需要刷新MainWindowTitle,最好检查一下空......就像这样:
import toastr from 'toastr';
答案 3 :(得分:7)
就像其他人已经说过的那样,你所要求的并不是很明显。我将假设你想要启动一个进程,然后在进程“准备就绪”时执行另一个操作。
当然,“准备就绪”是一个棘手的问题。根据您的需求,您可能会发现只需等待即可。但是,如果您需要更强大的解决方案,可以考虑使用命名Mutex来控制两个进程之间的控制流。
例如,在主进程中,您可以创建一个命名的互斥锁并启动一个等待的线程或任务。然后,您可以开始第二个过程。当该进程决定“它已准备就绪”时,它可以打开指定的互斥锁(当然,您必须使用相同的名称)并向第一个进程发出信号。
答案 4 :(得分:6)
首先:我知道这已经很老了,但仍然没有接受的答案,所以也许我的方法会帮助别人。 :)
我做的是解决这个问题:
process.Start();
while (true)
{
try
{
var time = process.StartTime;
break;
}
catch (Exception) {}
}
只要进程没有启动,关联var time = process.StartTime
就会抛出异常。因此,一旦通过,就可以安全地假设流程正在运行并进一步使用它。我正在使用它来等待java进程启动,因为它需要一些时间。这样,它应该独立于运行应用程序的机器,而不是使用Thread.Sleep()
。
我知道这不是一个非常干净的解决方案,但是我能想到的唯一一个应该与性能无关的解决方案。
答案 5 :(得分:4)
我同意汤姆的观点。此外,要在执行Thread.Sleep时检查进程,请检查正在运行的进程。类似的东西:
bool found = 0;
while (!found)
{
foreach (Process clsProcess in Process.GetProcesses())
if (clsProcess.Name == Name)
found = true;
Thread.CurrentThread.Sleep(1000);
}
答案 6 :(得分:2)
在子进程启动之前,您确定Start
方法是否返回?我始终认为Start
同步启动子进程。
如果您想等到子进程完成某种初始化,那么您需要进程间通信 - 请参阅 Interprocess communication for Windows in C# (.NET 2.0) 。
答案 7 :(得分:1)
为了扩展@ChrisG的想法,请考虑使用process.MainWindowHandle并查看窗口消息循环是否响应。使用p /调用此Win32 api:SendMessageTimeout。 从那个链接:
如果功能成功,则返回 值非零。 SendMessageTimeout 不提供有关的信息 如果,个别窗户超时 使用HWND_BROADCAST。
如果函数失败或超时,则返回值为0.要获取 扩展错误信息,调用 GetLastError函数。如果GetLastError返回 ERROR_TIMEOUT,然后函数定时 进行。
答案 8 :(得分:0)
这是一个使用System.Threading.Timer
的实现。为了它的目的可能有点多。
private static bool StartProcess(string filePath, string processName)
{
if (!File.Exists(filePath))
throw new InvalidOperationException($"Unknown filepath: {(string.IsNullOrEmpty(filePath) ? "EMPTY PATH" : filePath)}");
var isRunning = false;
using (var resetEvent = new ManualResetEvent(false))
{
void Callback(object state)
{
if (!IsProcessActive(processName)) return;
isRunning = true;
// ReSharper disable once AccessToDisposedClosure
resetEvent.Set();
}
using (new Timer(Callback, null, 0, TimeSpan.FromSeconds(0.5).Milliseconds))
{
Process.Start(filePath);
WaitHandle.WaitAny(new WaitHandle[] { resetEvent }, TimeSpan.FromSeconds(9));
}
}
return isRunning;
}
private static bool StopProcess(string processName)
{
if (!IsProcessActive(processName)) return true;
var isRunning = true;
using (var resetEvent = new ManualResetEvent(false))
{
void Callback(object state)
{
if (IsProcessActive(processName)) return;
isRunning = false;
// ReSharper disable once AccessToDisposedClosure
resetEvent.Set();
}
using (new Timer(Callback, null, 0, TimeSpan.FromSeconds(0.5).Milliseconds))
{
foreach (var process in Process.GetProcessesByName(processName))
process.Kill();
WaitHandle.WaitAny(new WaitHandle[] { resetEvent }, TimeSpan.FromSeconds(9));
}
}
return isRunning;
}
private static bool IsProcessActive(string processName)
{
return Process.GetProcessesByName(processName).Any();
}
答案 9 :(得分:0)
public static class WinApi
{
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
public static class Windows
{
public const int NORMAL = 1;
public const int HIDE = 0;
public const int RESTORE = 9;
public const int SHOW = 5;
public const int MAXIMIXED = 3;
}
}
应用
String process_name = "notepad"
Process process;
process = Process.Start( process_name );
while (!WinApi.ShowWindow(process.MainWindowHandle, WinApi.Windows.NORMAL))
{
Thread.Sleep(100);
process.Refresh();
}
// Done!
// Continue your code here ...
答案 10 :(得分:0)
我使用了EventWaitHandle类。在父进程上,创建一个名为EventWaitHandle的事件的初始状态设置为非信号状态。父进程将阻塞,直到子进程调用Set方法,将事件的状态更改为已通知,如下所示。
家长程序:
'AND'
子进程:
using System;
using System.Threading;
using System.Diagnostics;
namespace MyParentProcess
{
class Program
{
static void Main(string[] args)
{
EventWaitHandle ewh = null;
try
{
ewh = new EventWaitHandle(false, EventResetMode.AutoReset, "CHILD_PROCESS_READY");
Process process = Process.Start("MyChildProcess.exe", Process.GetCurrentProcess().Id.ToString());
if (process != null)
{
if (ewh.WaitOne(10000))
{
// Child process is ready.
}
}
}
catch(Exception exception)
{ }
finally
{
if (ewh != null)
ewh.Close();
}
}
}
}
答案 11 :(得分:0)
您还可以通过尝试以下操作来检查启动的进程是否响应: while(process.responding)