.NET活动的进程可执行文件开始

问题描述:

有没有办法为一个特定的文件名的可执行开始时触发一个事件注册?我知道当流程退出时,通过获取流程句柄并注册已退出的事件,可以轻松获得事件。但是,当一个没有运行的进程开始时,如何在没有轮询所有正在运行的进程的情况下如何通知您?.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对象从两家钟表*的方法,因为它实现IDisposable回来,所以你应该呼吁这些对象处置,当你与他们完成,以防止问题。

你也可以,如果你需要的情况下更快地进程已经启动之后提出更改查询轮询值。要做到这一点更改线路“在10”须于一些小于10

+0

这段代码可以被重构,但我已经把它放在了冗长的地方,希望有助于理解 – Clive 2009-05-13 15:42:36

+1

现在,这是一个答案!谢谢! – 2009-05-13 18:23:50

+0

实际上这个代码看起来不错。但它不适合我。我错过了任何一点? win7,net 2.o项目。 – Yaya 2011-09-11 11:16:48

创建过程时,WMI可以创建活动。您可以过滤这些事件。

+1

一个例子会很好:) – 2009-05-12 12:26:11

+0

@Adam:我在期待那个评论。不幸的是,自从我与WMI事件(年)一起工作了一段时间,而不是使用.NET,所以我将不得不自己学习如何做......而且现在没有时间。 – Richard 2009-05-12 16:52:16

这里是代码。

请注意,您必须启动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); 
      } 
     } 
    } 
}