c# - 如何知道外部应用程序是否已关闭?

标签 c# .net winforms

我怎么能说如果 winform whas closed do ...?

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

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

最佳答案

您可以使用 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 线程不同的线程中引发,如果您需要操作 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");
    }
    

关于c# - 如何知道外部应用程序是否已关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39703399/

相关文章:

c# - Winforms应用程序可以解锁/替换自己的exe文件以进行自动更新吗?

c# - 如何在不下载所有页面源的情况下始终获取网站标题

c# - 在 cshtml 页面内异步加载

c# - 计算2个3维点之间距离的算法?

c# - MemoryStream 到虚拟文件

.net - 使用 {0 :C}? 格式化小于 1.00 的值

c# - 当 T 可以是 IEnumerable<T> 时实现 IEquatable<T>

.net - ELMAH与企业库异常处理 block

.net - 如何判断连接是否按流量计费?

c# - 背景 worker 。如何通过在 TreeView 中导航来显示当前进程?