2010-10-25 19 views
4

J'essaie de surveiller les lecteurs d'un PC local. Je suis intéressé par deux événements: lorsque le lecteur est connecté (clé USB, CD-ROM, lecteur réseau, etc.) et déconnecté. J'ai écrit une preuve de concept rapide en utilisant le ManagementOperationObserver et cela fonctionne partiellement. En ce moment (avec le code ci-dessous), je reçois toutes sortes d'événements. Je voudrais obtenir seulement des événements quand un lecteur est connecté et déconnecté. Existe-t-il un moyen de spécifier cela dans la requête Wql?Surveillance des lecteurs avec WMI

Merci!

private void button2_Click(object sender, EventArgs e) 
    { 
     t = new Thread(new ParameterizedThreadStart(o => 
     { 
      WqlEventQuery q; 
      ManagementOperationObserver observer = new ManagementOperationObserver(); 

      ManagementScope scope = new ManagementScope("root\\CIMV2"); 
      scope.Options.EnablePrivileges = true; 

      q = new WqlEventQuery(); 
      q.EventClassName = "__InstanceOperationEvent"; 
      q.WithinInterval = new TimeSpan(0, 0, 3); 
      q.Condition = @"TargetInstance ISA 'Win32_LogicalDisk' "; 
      w = new ManagementEventWatcher(scope, q); 

      w.EventArrived += new EventArrivedEventHandler(w_EventArrived); 
      w.Start(); 
     })); 

     t.Start(); 
    } 

    void w_EventArrived(object sender, EventArrivedEventArgs e) 
    { 
     //Get the Event object and display its properties (all) 
     foreach (PropertyData pd in e.NewEvent.Properties) 
     { 
      ManagementBaseObject mbo = null; 
      if ((mbo = pd.Value as ManagementBaseObject) != null) 
      { 
       this.listBox1.BeginInvoke(new Action(() => listBox1.Items.Add("--------------Properties------------------"))); 
       foreach (PropertyData prop in mbo.Properties) 
        this.listBox1.BeginInvoke(new Action<PropertyData>(p => listBox1.Items.Add(p.Name + " - " + p.Value)), prop); 
      } 
     } 
    } 
+0

Commentaire rapide: Vous n'avez pas besoin d'utiliser ParameterizedThreadStart car vous n'utilisez pas le paramètre. Utilisez simplement ThreadStart. –

Répondre

5

Vous y êtes presque. Pour distinguer un lecteur connecté à une machine et un lecteur à être supprimé, vous devez vérifier si e.NewEvent est une instance de __InstanceCreationEvent ou __InstanceDeletionEvent respectivement. Quelque chose le long de ces lignes:

ManagementBaseObject baseObject = (ManagementBaseObject) e.NewEvent; 

if (baseObject.ClassPath.ClassName.Equals("__InstanceCreationEvent")) 
    Console.WriteLine("A drive was connected"); 
else if (baseObject.ClassPath.ClassName.Equals("__InstanceDeletionEvent")) 
    Console.WriteLine("A drive was removed"); 

De plus, vous pouvez également obtenir l'instance Win32_LogicalDisk via la propriété TargetInstance.

ManagementBaseObject logicalDisk = 
       (ManagementBaseObject) e.NewEvent["TargetInstance"]; 

Console.WriteLine("Drive type is {0}", 
        logicalDisk.Properties["DriveType"].Value);