2009-05-11 7 views
20

Gibt es eine Möglichkeit, sich für ein Ereignis zu registrieren, das ausgelöst wird, wenn eine ausführbare Datei eines bestimmten Dateinamens gestartet wird? Ich weiß, dass es einfach ist, ein Ereignis zu erhalten, wenn ein Prozess beendet wird, indem das Prozesshandle abgerufen und für das beendete Ereignis registriert wird. Aber wie kann man benachrichtigt werden, wenn ein Prozess, der noch nicht läuft, gestartet wird ... ohne alle laufenden Prozesse abzufragen?.NET-Ereignisse für den ausführbaren Prozessprozess

Antwort

30

könnten Sie Folgendes verwenden:

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)); 
    } 

Sie würden dann entweder WatchForProcessStart und/oder WatchForProcessEnd im Prozessnamen (zB "notepad.exe"), die nennen.

Das ManagementEventWatcher-Objekt wird von den beiden Watch * -Methoden zurückgegeben, da IDisposable implementiert wird. Daher sollten Sie Dispose für diese Objekte aufrufen, wenn Sie damit fertig sind, um Probleme zu vermeiden.

Sie können den Abfragewert in den Abfragen auch ändern, wenn das Ereignis nach dem Start des Prozesses schneller ausgelöst werden soll. Um dies zu tun, ändern Sie die Zeile "WITHIN 10" in etwas weniger als 10 sein.

+0

Dieser Code könnte refaktoriert werden, aber ich habe es ausführlich gelassen, um das Verständnis zu erleichtern – Clive

+1

Nun, das ist eine Antwort! Vielen Dank! –

+0

eigentlich sieht dieser Code gut aus. Aber es funktioniert nicht für mich. Ich vermisse jeden Punkt? win7, net 2.o project. – Yaya

3

WMI kann Ereignisse erstellen, wenn Prozesse erstellt werden. Sie könnten diese Ereignisse dann filtern.

+1

Ein Beispiel wäre nett :) –

+0

@Adam: Ich habe diesen Kommentar erwartet. Leider ist es schon eine Weile her, dass ich mit WMI-Events (Jahren) gearbeitet habe, und nicht mit .NET, also müsste ich lernen, wie ich es selbst mache ... und momentan keine Zeit habe. – Richard

1

Hier ist Code.

Beachten Sie, dass Sie Visual Studio wie Administrator starten müssen, um diesen Code auszuführen.

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); 
      } 
     } 
    } 
} 
Verwandte Themen