如何知道外部申请是否已关闭?

时间:2016-09-26 12:52:42

标签: c# .net winforms

如果winform关闭了怎么说呢?

bool isRunning = false;
foreach (Process clsProcess in Process.GetProcesses()) 
{
    if (clsProcess.ProcessName.Contains("Notepad"))
    {
        isRunning = true;
        break;
    }
}

上面的代码总是检查进程是否存在,但代码对我想做的事情来说很慢。那么有没有办法检查Notepad进程是否实际关闭而不是总是循环查看是否它在那里?

3 个答案:

答案 0 :(得分:8)

您可以使用Win32_ProcessStopTrace表示进程已终止。

ManagementEventWatcher watcher;
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    watcher = new ManagementEventWatcher("Select * From Win32_ProcessStopTrace");
    watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
    watcher.Start();
}

void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
    if ((string)e.NewEvent["ProcessName"] == "notepad.exe")
        MessageBox.Show("Notepad closed");
}

protected override void OnFormClosed(FormClosedEventArgs e)
{
    watcher.Stop();
    watcher.Dispose();
    base.OnFormClosed(e);
}

不要忘记添加对System.Management的引用并添加using System.Management;

注意

  • 如果您想要监控您知道的特定记事本实例的关闭,您可以使用以下标准:

    if ((UInt32)e.NewEvent["ProcessID"]==knownProcessId)
    
  • 如果您想检查记事本的任何实例是否已打开,您可以使用以下标准:

    if (System.Diagnostics.Process.GetProcessesByName("notepad").Any())
    
  • EventArrived将在与线程不同的线程中引发,如果您需要操作UI,则需要使用Invoke

  • 上述方法会通知您在应用程序运行之前或之后关闭所有进程,无论它们何时打开。如果您不希望收到有关应用程序启动后可能会打开的进程的通知,您可以获取现有的记事本进程并订阅他们的Exited事件:

    private void Form1_Load(object sender, EventArgs e)
    {
        System.Diagnostics.Process.GetProcessesByName("notepad").ToList()
              .ForEach(p => {
                  p.EnableRaisingEvents = true;
                  p.Exited += p_Exited;
              });
    }
    void p_Exited(object sender, EventArgs e)
    {
        MessageBox.Show("Notepad closed");
    }
    

答案 1 :(得分:2)

你可以在没有循环的情况下完成它,但不知道它是否更快:

bool isRunning = Process.GetProcessesByName("NotePad").FirstOrDefault() != null;

bool isRunning = Process.GetProcessesByName("notepad").Any();

我从这里得到了这个Check if a specific exe file is running

答案 2 :(得分:2)

这应该可以解决问题。当进程终止时,它将为您创建一个事件。无需遍历所有过程。

public static event EventHandler ProcessDied;
public void CheckForProcess()
{

    InitializeComponent();
    ProcessDied += new EventHandler(Process_Died);
    AttachProcessDiedEvent("notepad", ProcessDied);

}

private  void AttachProcessDiedEvent( string processName,EventHandler e )
{
    Process isSelectedProcess=null;
    foreach (Process clsProcess in Process.GetProcesses())
    {
        if (clsProcess.ProcessName.Contains(processName))
        {
            isSelectedProcess = clsProcess;
            break;
        }
    }
    if(isSelectedProcess!=null)
    {
         isSelectedProcess.WaitForExit();
    }
    if(e!=null)
    {
        e.Invoke(processName, new EventArgs());
    }
}

private void Process_Died(object sender, EventArgs e)
{
    //Do Your work
}

如果有任何问题,请告诉我。