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

13,488

Solution 1

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"].

Solution 2

EDIT 1: Oh is see that it is not a USB storage device but only a USB device. I will look for another solution.


Two links that describe the same problem:

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

Solution 3

When I tried @AngryHacker solution, I noticed that the DeviceChangedEventArgs class did not ever get called, though. I removed it and just added Console.WriteLines() in the watcher_eventArrived methods.

Besides the deletion of the DeviceChangedEventArgs, here are my changes:

 (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
Share:
13,488
AngryHacker
Author by

AngryHacker

Updated on June 05, 2022

Comments

  • AngryHacker
    AngryHacker almost 2 years

    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.

  • AngryHacker
    AngryHacker almost 11 years
    The deviceID is fine and good, but how do I get the name of the actual device, e.g. Sennheiser USB headset.
  • Simon Mourier
    Simon Mourier almost 11 years
    Have you tried running that code without the GUID_DEVCLASS_USB check I've put there? It may be identified as another type (class) of device. Plugging a USB drive for example may raise many events (USB device, Hard disk, Volume, etc.)
  • AngryHacker
    AngryHacker almost 11 years
    Yes, I have, but I face the same problem: it gives me everything except the actual device name.
  • AngryHacker
    AngryHacker almost 11 years
    I see a fellow JC Hutchins fan :)
  • AngryHacker
    AngryHacker almost 11 years
    Ok, I got it halfways through. Instead of GUID_DEVCLASS_USB, I filtered on GUID_DEVCLASS_MEDIA ({4D36E96C-E325-11CE-BFC1-08002BE10318}) and that did the trick. Now, the only remaining piece is to detect when the device is unplugged.
  • Simon Mourier
    Simon Mourier almost 11 years
    For that, you need to monitor on __InstanceOperationEvent, not just __InstanceCreationEvent, you will get creation, deletion and modification events in the same sink. PS: actually, I'm more a Tex Avery fan kilroywashere.org/01-Images/MattThKilroy/Page4/… :-)
  • AngryHacker
    AngryHacker almost 11 years
    That did the trick, except it was the __InstanceDeletionEvent. Full solution is at pastebin.com/amLAHuEa
  • Raulp
    Raulp about 10 years
    Even with GUID_DEVCLASS_USB it the code developed by AngryHacker is able to detect the name of the USB drive.Does that means all the USB devices' insertion/removal will be detected by this piece of code.I tried with following devices : USB Hub : -> it shows it as USB 2.0 hub, for USB drive : -> It shows Name of the USB manufacturer HP pen-drive , for USB Keyboard Dongle -> it gives name as Composite Device ,But it never gives removal events for first and last device.Any comments
  • Micah Vertal
    Micah Vertal over 7 years
    For me everything works but the filtering of the "ClassGuid". I get a System.Management.ManagementException which says the property is not found. I am using a USB Flash drive, but it doesn't work for other devices as well (i.e. a keyboard or mouse).