2009-05-11 6 views
20

Y a-t-il un moyen de s'enregistrer pour un événement qui se déclenche lorsqu'un exécutable d'un nom de fichier particulier démarre? Je sais qu'il est assez facile d'obtenir un événement quand un processus se termine, en obtenant le traitement du processus et en vous inscrivant à l'événement quitté. Mais comment pouvez-vous être averti quand un processus, qui n'est pas déjà lancé, démarre ... sans interroger tous les processus en cours?.NET Evénements pour le processus Exécutable exécutable

Répondre

30

Vous pouvez utiliser les éléments suivants:

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

Vous appelleriez alors soit WatchForProcessStart et/ou WatchForProcessEnd passant votre nom de processus (par exemple "notepad.exe"). L'objet ManagementEventWatcher est renvoyé à partir des deux méthodes Watch * car il implémente IDisposable. Vous devez donc appeler Dispose sur ces objets lorsque vous en avez terminé avec eux pour éviter les problèmes.

Vous pouvez également modifier la valeur d'interrogation dans les requêtes si vous souhaitez que l'événement soit levé plus rapidement après le démarrage du processus. Pour ce faire, changez la ligne "WITHIN 10" pour qu'elle soit quelque chose de moins de 10.

+0

Ce code pourrait être refactorisé, mais je l'ai laissé verbeux pour aider à aider la compréhension – Clive

+1

Maintenant, c'est une réponse! Merci! –

+0

en fait ce code a l'air bien. Mais ça ne marche pas pour moi. Il me manque un point? win7, net 2.o projet. – Yaya

3

WMI peut créer des événements lorsque des processus sont créés. Vous pouvez ensuite filtrer ces événements.

+1

Un exemple serait bien :) –

+0

@Adam: Je m'attendais à ce commentaire. Malheureusement, cela faisait un moment que je travaillais avec des événements WMI (années), et pas avec .NET donc je devais apprendre à le faire moi-même ... et je n'ai pas le temps en ce moment. – Richard

1

Voici le code.

Notez que vous devez démarrer Visual Studio comme Administrateur afin d'exécuter ce code.

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