用于Process可执行文件的.NET事件

是否有任何方法可以注册在特定文件名的可执行文件启动时触发的事件? 我知道,当进程退出时,通过获取进程句柄并注册已退出的事件,可以轻松获取事件。 但是,当一个尚未运行的进程启动时,如何在不轮询所有正在运行的进程的情况下,如何通知您?

您可以使用以下内容:

private ManagementEventWatcher WatchForProcessStart(string processName) { string queryString = "SELECT TargetInstance" + " FROM __InstanceCreationEvent " + "WITHIN 10 " + " WHERE TargetInstance ISA 'Win32_Process' " + " AND TargetInstance.Name = '" + processName + "'"; // The dot in the scope means use the current machine string scope = @"\\.\root\CIMV2"; // Create a watcher and listen for events ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString); watcher.EventArrived += ProcessStarted; watcher.Start(); return watcher; } private ManagementEventWatcher WatchForProcessEnd(string processName) { string queryString = "SELECT TargetInstance" + " FROM __InstanceDeletionEvent " + "WITHIN 10 " + " WHERE TargetInstance ISA 'Win32_Process' " + " AND TargetInstance.Name = '" + processName + "'"; // The dot in the scope means use the current machine string scope = @"\\.\root\CIMV2"; // Create a watcher and listen for events ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString); watcher.EventArrived += ProcessEnded; watcher.Start(); return watcher; } private void ProcessEnded(object sender, EventArrivedEventArgs e) { ManagementBaseObject targetInstance = (ManagementBaseObject) e.NewEvent.Properties["TargetInstance"].Value; string processName = targetInstance.Properties["Name"].Value.ToString(); Console.WriteLine(String.Format("{0} process ended", processName)); } private void ProcessStarted(object sender, EventArrivedEventArgs e) { ManagementBaseObject targetInstance = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value; string processName = targetInstance.Properties["Name"].Value.ToString(); Console.WriteLine(String.Format("{0} process started", processName)); } 

然后,您将调用WatchForProcessStart和/或WatchForProcessEnd传入您的进程名称(例如“notepad.exe”)。

ManagementEventWatcher对象是从两个Watch *方法返回的,因为它实现了IDisposable,所以你应该在完成这些对象后调用Dispose以防止出现问题。

如果您需要在进程启动后更快地引发事件,还可以更改查询中的轮询值。 要执行此操作,请将“WITHIN 10”行更改为少于10的WITHIN。

WMI可以在创建进程时创建事件。 然后,您可以过滤这些事件。

这是代码。

请注意,您必须像管理员一样启动Visual Studio才能执行此代码。

 using System; using System.Management; namespace AppLaunchDetector { class Program { static void Main(string[] args) { ManagementEventWatcher w = null; WqlEventQuery q; try { q = new WqlEventQuery(); q.EventClassName = "Win32_ProcessStartTrace"; w = new ManagementEventWatcher(q); w.EventArrived += new EventArrivedEventHandler(ProcessStartEventArrived); w.Start(); Console.ReadLine(); // block main thread for test purposes } catch (Exception ex) { } finally { w.Stop(); } } static void ProcessStartEventArrived(object sender, EventArrivedEventArgs e) { foreach (PropertyData pd in e.NewEvent.Properties) { Console.WriteLine("\n============================= ========="); Console.WriteLine("{0},{1},{2}", pd.Name, pd.Type, pd.Value); } } } }