C# – Catch USB plug and unplug event

When I am making a review of session 0 and windows service, I would like to write a small example to detect the plug and unplug event of USB stick and attach it to windows service. I used ManangementEventWatcher class to subscribe to temporary event notifications based on a specified event query. This query is a type of WqlEventQuery class which represents a WMI event query in WQL format.

1. Introduction

WqlEventQuery weqQuery = new WqlEventQuery();
weqQuery.EventClassName = "__InstanceOperationEvent";
weqQuery.WithinInterval = new TimeSpan(0, 0, 3);
weqQuery.Condition = @"TargetInstance ISA 'Win32_DiskDrive'";

The WMI Query Language (WQL) is a subset of the American National Standards Institute Structured Query Language (ANSI SQL)—with minor semantic changes. This initialization above is equivalent to the WQL below whereas __InstanceOperationEvent serves as a base class for all intrinsic events that relate to an instance.

string strQueryString =
@"SELECT *
FROM __InstanceOperationEvent
WITHIN 3
WHERE
TargetInstance ISA 'Win32_DiskDrive'";

__InstaceOperationEvent is a type of WMI System Classes. The WMI system classes are a collection of predefined classes based on the Common Information Model (CIM). Unlike classes supplied by providers, the system classes are not declared in a Managed Object Format (MOF) file.
Objects from the system classes are used to support WMI activities, such as event and provider registration, security, and event notification. Some objects are temporary, and some are stored in the repository as instances of the system classes
. For more information about WMI System Classes, you can read at following link http://msdn.microsoft.com/en-us/library/aa394583%28VS.85%29.aspx

After a declaration of query event, we can now bind it with a listener

 m_mewWatcher = new ManagementEventWatcher(msScope, weqQuery);
m_mewWatcher.EventArrived += new EventArrivedEventHandler(m_mewWatcher_EventArrived);
m_mewWatcher.Start();

In the code handling EventArrive, we’ll check out if the event relates to USB.

static void m_mewWatcher_EventArrived(object sender, EventArrivedEventArgs e)
{
	
	bool bUSBEvent = false;
   
	foreach (PropertyData pdData in e.NewEvent.Properties)
	{
		ManagementBaseObject mbo = (ManagementBaseObject) pdData.Value;
		if (mbo != null)
		{                    
			foreach (PropertyData pdDataSub in mbo.Properties)
			{
				if (pdDataSub.Name == "InterfaceType" && pdDataSub.Value.ToString() == "USB")
				{
					bUSBEvent = true;
					break;
				}
			}

			if (bUSBEvent)
			{
				if (e.NewEvent.ClassPath.ClassName == "__InstanceCreationEvent")
				{
					Console.WriteLine("USB was plugged in");
				}
				else if (e.NewEvent.ClassPath.ClassName == "__InstanceDeletionEvent")
				{
					Console.WriteLine("USB was plugged out");
				}
			}
		}
	}
}

2. Source code

The complete of working source code you can download at: https://bitbucket.org/hintdesk/dotnet-catch-usb-plug-and-unplug-event
You can expand the application by attaching it to a windows service.

3. Updates

3.1 Update 12.04.2012

Get disk name of USB Device after being plugged in.

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

4 thoughts on “C# – Catch USB plug and unplug event”

  1. Great! This got me started right on.
    I wanted to detect when a USB to SerialPort devicedriver was loaded, and this example was just what I needed.

    Thanks

  2. Hi,

    Great example! We notice that sometimes the event seems to be out of sync if you insert an USB device in and out fast, and eventually the eventhandler for USBDeviceAdded is not called when you insert a USB memory for instance. do you have any tip how to improve on this?

    Bjorn

Leave a Reply

Your email address will not be published. Required fields are marked *