简体   繁体   English

如何确定流程是否已启动但尚未退出?

[英]How to determine if a Process has started but not yet exited?

I have some code that creates a Process instance and later starts it. 我有一些代码可以创建一个Process实例,然后启动它。 There's some logic that need to check if the Process has been started. 有一些逻辑需要检查Process是否已经启动。 HasExited can be used to check if a started process has been exited, but I can not find a similar function for HasStarted . HasExited可用于检查是否已退出已启动的进程,但我找不到HasStarted的类似函数。 At first glance StartTime looked like a good option, but this function will throw if the process has exited. 乍一看, StartTime看起来是一个不错的选择,但是如果进程退出,这个函数将抛出。 Also, the documentation says that StartTime only has meaning for started processes. 此外,文档说StartTime只对启动的进程有意义。

What is the "correct" approach for determining if a process has started (has been started, but might have quit)? 确定流程是否已启动(已启动但可能已退出)的“正确”方法是什么?

Search your process in Process.GetProcesses(); Process.GetProcesses();搜索您的流程Process.GetProcesses(); , the list returned by this method give all processes currently running on the machine. ,此方法返回的列表提供当前在计算机上运行的所有进程。

While the methods suggested by others will work, it is not the most efficient way to handle such things. 虽然其他人建议的方法可行,但它并不是处理此类事情的最有效方法。 If you keep a loop checking whether the Process has exited or not, you will waste a lot of system resources. 如果您保持循环检查进程是否已退出,则会浪费大量系统资源。 Your concern should be to just know when the process is exiting, and not sit looping for it to check whether it has exited. 您应关注的是只知道流程何时退出,而不是坐下来检查流程是否已退出。 So, the correct way is to handle Events. 所以,正确的方法是处理事件。

The code below explains how to do that using Events. 下面的代码解释了如何使用事件来做到这一点。

// Declare your process object with WithEvents, so that events can be handled.
private Process withEventsField_MyProcess;
Process MyProcess {
    get { return withEventsField_MyProcess; }
    set {
        if (withEventsField_MyProcess != null) {
            withEventsField_MyProcess.Exited -= MyProcess_Exited;
        }
        withEventsField_MyProcess = value;
        if (withEventsField_MyProcess != null) {
            withEventsField_MyProcess.Exited += MyProcess_Exited;
        }
    }
}

bool MyProcessIsRunning;
private void Button1_Click(System.Object sender, System.EventArgs e)
{
    // start the process. this is an example.
    MyProcess = Process.Start("Notepad.exe");

    // enable raising events for the process.
    MyProcess.EnableRaisingEvents = true;

    // set the flag to know whether my process is running
    MyProcessIsRunning = true;
}

private void MyProcess_Exited(object sender, System.EventArgs e)
{
    // the process has just exited. what do you want to do?
    MyProcessIsRunning = false;
    MessageBox.Show("The process has exited!");
}

EDIT: Knowing whether the process has started or not should be easy since are starting the process somewhere in the code. 编辑:知道进程是否已经开始应该很容易,因为在代码中的某个地方开始进程。 So you can set a flag there and set it to false when the process is exiting. 因此,您可以在那里设置一个标志,并在进程退出时将其设置为false。 I updated the code above to show how such a flag can be set easily. 我更新了上面的代码,以显示如何轻松设置这样的标志。

You can use the Process.GetProcesses method (in the System.Diagnostics namespace) to get a list of processes currently running on the PC. 您可以使用Process.GetProcesses方法(在System.Diagnostics命名空间中)获取当前在PC上运行的进程列表。

Process.GetProcessesByName() can also be used to just get a list of instances of a particular program. Process.GetProcessesByName()也可用于获取特定程序的实例列表。

// Get all instances of Notepad running on the local computer.
Process [] localByName = Process.GetProcessesByName("YourProcess");

You could check that there is atleast one thread in the process. 您可以检查过程中至少有一个线程 This would indicate that the process is started and running. 这表明该过程已启动并正在运行。

Edit: 编辑:
You could also check the process Id . 您还可以检查进程ID It will throw an exception if the process hasn't started. 如果进程尚未启动,它将抛出异常。

Edit 2: 编辑2:
Actually Threads will also throw an exception if the Id is not set: 实际上,如果没有设置Id, Threads也会抛出异常:

bool ProcessIsRunning(Process p)
{
  bool isRunning;
  try {
    isRunning = !p.HasExited && p.Threads.Count > 0;
  }
  catch(SystemException sEx)
  {
    isRunning = false;
  }
  catch(PlatformNotSupportedException pnsEx)
  {
    throw;
  }

  return isRunning;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM