如何知道外部申请是否已关闭?
如果一个winform关闭了怎么说呢?
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;
添加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"); }
这应该可以解决问题。 当进程终止时,它将为您创建一个事件。 无需遍历所有过程。
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 }
如果有任何问题,请告诉我。
你可以不循环但不知道它是否更快:
bool isRunning = Process.GetProcessesByName("NotePad").FirstOrDefault() != null;
要么
bool isRunning = Process.GetProcessesByName("notepad").Any();
我从这里得到这个检查特定的exe文件是否正在运行