Search code examples
c#usbwmiplug-and-play

How to identify what device was plugged into the USB slot?


I want to detect when the user plugs in or removes a USB sound card. I've managed to actually catch the event when this happens, but I can't tell what just got plugged in.

I tried an approach based on this question:

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

While I get the notifications via the EventArrived event, I have no idea how to determine the actual name of the device that just got plugged in. I've gone through every property and couldn't make heads or tails out of it.

I also tried a different query:

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

but also to no avail. Is there a way to find the name of the device that got plugged in or removed.

The bottom line is that I'd like to know when a USB sound card is plugged in or removed from the system. It should work on Windows 7 and Vista (though I will settle for Win7 only).

EDIT: Based on the suggestions by the winning submitter, I've created a full solution that wraps all the functionality.


Solution

  • If I use your first code, I can define my event like this:

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

    And this will dump something like this:

    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
    

    This should contain everything you need, including the device ID that you can get with something like instance["DeviceID"].