2009-05-11 4 views
20

Есть ли способ зарегистрировать событие, которое запускается при запуске исполняемого файла определенного имени файла? Я знаю, что достаточно легко получить событие, когда процесс завершается, получая дескриптор процесса и регистрируясь для выходящего события. Но как вы можете получать уведомления, когда процесс, который еще не запущен, запускается ... без опроса всех запущенных процессов?События .NET для запуска исполняемого файла процесса

ответ

30

Вы можете использовать следующее:

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 на этих объектах, когда вы закончили с ними, чтобы предотвратить проблемы.

Вы также можете изменить значение опроса в запросах, если вам нужно, чтобы событие было увеличено быстрее после начала процесса. Чтобы сделать это, измените строку «ВИН 10» на то, что будет меньше 10.

+0

Этот код может быть реорганизован, но я оставил его многословным, чтобы надеяться на понимание. – Clive

+1

Теперь это ответ! Благодаря! –

+0

На самом деле этот код выглядит хорошо. Но это не работает для меня. Мне не хватает какой-либо точки? win7, net 2.o. – Yaya

3

WMI может создавать события при создании процессов. Затем вы можете отфильтровать эти события.

+1

Пример будет приятным :) –

+0

@Adam: Я ожидал этого комментария. К сожалению, прошло некоторое время с тех пор, как я работал с событиями WMI (годы), а не с .NET, поэтому мне пришлось бы научиться самому делать это ... и не иметь времени на данный момент. – Richard

1

Вот код.

Обратите внимание, что для выполнения этого кода необходимо запустить Visual Studio, например, Administrator.

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); 
      } 
     } 
    } 
} 
Смежные вопросы