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

Joh*_*rar 4 .net c# winforms

如果一个winform关闭了怎么说呢?

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

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

Rez*_*aei 9

您可以使用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);
}
Run Code Online (Sandbox Code Playgroud)

不要忘记添加引用System.Management和添加using System.Management;

注意

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

    if ((UInt32)e.NewEvent["ProcessID"]==knownProcessId)
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果要检查是否打开了任何记事本实例,可以使用以下标准:

    if (System.Diagnostics.Process.GetProcessesByName("notepad").Any())
    
    Run Code Online (Sandbox Code Playgroud)
  • 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");
    }
    
    Run Code Online (Sandbox Code Playgroud)