2013-05-18 17 views
12

Voglio rilevare quando l'utente inserisce o rimuove una scheda audio USB. Sono riuscito a catturare in realtà l'evento quando questo accade, ma non posso dire che cosa ha ottenuto appena collegatoCome identificare quale dispositivo è stato inserito nello slot USB?

ho provato un approccio basato su this domanda:.

string query = 
    "SELECT * FROM __InstanceCreationEvent " + 
    "WITHIN 2 " 
    + "WHERE TargetInstance ISA 'Win32_PnPEntity'"; 
var watcher = new ManagementEventWatcher(query); 
watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived); 
watcher.Start(); 

Mentre ricevo le notifiche tramite l'evento EventArrived, non ho idea di come determinare il nome effettivo del dispositivo che è appena stato collegato. Ho esaminato tutte le proprietà e non sono riuscito a farne testa o croce.

Ho anche provato una query diversa:

var query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent where EventType = 1 or EventType = 2"); 
var watcher = new ManagementEventWatcher(query); 
watcher.EventArrived += watcher_EventArrived; 
watcher.Stopped += watcher_Stopped; 
watcher.Query = query; 
watcher.Start(); 

ma anche senza alcun risultato. C'è un modo per trovare il nome del dispositivo che è stato collegato o rimosso.

La linea di fondo è che mi piacerebbe sapere quando una scheda audio USB è collegata o rimossa dal sistema. Dovrebbe funzionare su Windows 7 e Vista (anche se mi accontenterò solo di Win7).

MODIFICA: Sulla base dei suggerimenti del submitter vincente, ho creato uno full solution che include tutte le funzionalità.

+0

Cosa succede ad usare l'evento RegisterDeviceNotification? utilizzato in questa libreria ad esempio: https://code.google.com/p/winusbnet/ –

+0

@ SimonMourier Questa libreria sembra essere più utile per comunicare con dispositivi USB anziché rilevarli. Non vedo alcun esempio che mostri come rilevare i dispositivi, né vedo nulla nell'API che si presta a questo scopo. – AngryHacker

risposta

9

Se uso il vostro primo codice, posso definire il mio evento come questo:

// define USB class guid (from devguid.h) 
    static readonly Guid GUID_DEVCLASS_USB = new Guid("{36fc9e60-c465-11cf-8056-444553540000}"); 

    static void watcher_EventArrived(object sender, EventArrivedEventArgs e) 
    { 
     ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"]; 
     if (new Guid((string)instance["ClassGuid"]) == GUID_DEVCLASS_USB) 
     { 
      // we're only interested by USB devices, dump all props 
      foreach (var property in instance.Properties) 
      { 
       Console.WriteLine(property.Name + " = " + property.Value); 
      } 
     } 
    } 

E questo sarà il dump qualcosa di simile:

Availability = 
Caption = USB Mass Storage Device 
ClassGuid = {36fc9e60-c465-11cf-8056-444553540000} 
CompatibleID = System.String[] 
ConfigManagerErrorCode = 0 
ConfigManagerUserConfig = False 
CreationClassName = Win32_PnPEntity 
Description = USB Mass Storage Device 
DeviceID = USB\VID_18A5&PID_0243\07072BE66DD78609 
ErrorCleared = 
ErrorDescription = 
HardwareID = System.String[] 
InstallDate = 
LastErrorCode = 
Manufacturer = Compatible USB storage device 
Name = USB Mass Storage Device 
PNPDeviceID = USB\VID_18A5&PID_0243\07072BE66DD78609 
PowerManagementCapabilities = 
PowerManagementSupported = 
Service = USBSTOR 
Status = OK 
StatusInfo = 
SystemCreationClassName = Win32_ComputerSystem 
SystemName = KILROY_WAS_HERE 

Questo dovrebbe contenere tutto il necessario, compreso l'ID del dispositivo che si può ottenere con qualcosa di simile instance["DeviceID"].

+0

Il deviceID va bene e va bene, ma come ottengo il nome del dispositivo attuale, ad es. 'Auricolare USB Sennheiser'. – AngryHacker

+0

Hai provato a eseguire quel codice senza il controllo GUID_DEVCLASS_USB che ho inserito? Può essere identificato come un altro tipo (classe) di dispositivo. Il collegamento di un'unità USB, ad esempio, potrebbe generare molti eventi (dispositivo USB, disco rigido, volume, ecc.) –

+0

Sì, lo sono, ma ho lo stesso problema: mi dà tutto tranne il nome effettivo del dispositivo. – AngryHacker

3

EDIT 1: Oh si vede che non è un dispositivo di archiviazione USB ma solo un dispositivo USB. Cercherò un'altra soluzione.


due link che descrivono lo stesso problema:

http://hintdesk.com/c-catch-usb-plug-and-unplug-event/

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/37123526-83fa-4e96-a767-715fe225bf28/

if (e.NewEvent.ClassPath.ClassName == "__InstanceCreationEvent") 
{ 
    Console.WriteLine("USB was plugged in"); 
    //Get disk letter 
    foreach (ManagementObject partition in new ManagementObjectSearcher(
"ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + mbo.Properties["DeviceID"].Value 
+ "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get()) 
    { 
     foreach (ManagementObject disk in new ManagementObjectSearcher(
        "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" 
         + partition["DeviceID"] 
         + "'} WHERE AssocClass = Win32_LogicalDiskToPartition").Get()) 
     { 
      Console.WriteLine("Disk=" + disk["Name"]); 
     } 
    } 
} 
0

Quando ho provato la soluzione @AngryHacker, ho notato che la classe DeviceChangedEventArgs non è mai stata chiamata, comunque. L'ho rimosso e ho appena aggiunto Console.WriteLines() nei metodi watcher_eventArrived.

Oltre alla cancellazione del DeviceChangedEventArgs, qui sono le mie modifiche:

(at line 46 in EstablishedWatchEvents) 
// setup the query to monitor removal 
const string qryRemoval = "SELECT *" + "FROM __InstanceDeletionEvent " 
      + "WITHIN 2 " + "WHERE TargetInstance ISA 'Win32_PnPEntity' "; 

#region Events 

private void insertWatcher_EventArrived(object sender, EventArrivedEventArgs e) 
{ 

    var mbo = (ManagementBaseObject) e.NewEvent["TargetInstance"]; 
    if (new Guid((string) mbo["ClassGuid"]) == GUID_DEVCLASS_USB) 
    { 
     var deviceName = (string) mbo["Name"]; 
     Console.WriteLine(deviceName + " was inserted"); 

    } 
} 

private void removeWatcher_EventArrived(object sender, EventArrivedEventArgs e) 
{ 

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

    if (new Guid((string)mbo["ClassGuid"]) == GUID_DEVCLASS_USB) 
    { 
     var deviceName = (string)mbo["Name"]; 
     Console.WriteLine(deviceName + " was removed"); 
    } 
} 

#endregion 
Problemi correlati