Detecting insert and remove a USB drive using windows and C # service

Enabling the ability to create a distributed USB application
what will autostart when you insert a USB drive and stop when you remove the stick

Will use .Net and C #.
Looking for a suggestion on how to approach this with C #?

< / "> Update: two possible solutions that implement this as a service.
- override WndProc
or
- using a WMI request with ManagementEventWatcher

+57
c # windows wmi windows-services
Mar 6 '09 at 19:40
source share
9 answers

You can use WMI, it is simple and works much better than the WndProc services solution.

Here is a simple example:

using System.Management; ManagementEventWatcher watcher = new ManagementEventWatcher(); WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_VolumeChangeEvent WHERE EventType = 2"); watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived); watcher.Query = query; watcher.Start(); watcher.WaitForNextEvent(); 
+53
Jun 07 '10 at 10:08
source share

This works well for me, plus you can find out more information about the device.

 using System.Management; private void DeviceInsertedEvent(object sender, EventArrivedEventArgs e) { ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"]; foreach (var property in instance.Properties) { Console.WriteLine(property.Name + " = " + property.Value); } } private void DeviceRemovedEvent(object sender, EventArrivedEventArgs e) { ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"]; foreach (var property in instance.Properties) { Console.WriteLine(property.Name + " = " + property.Value); } } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { WqlEventQuery insertQuery = new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'"); ManagementEventWatcher insertWatcher = new ManagementEventWatcher(insertQuery); insertWatcher.EventArrived += new EventArrivedEventHandler(DeviceInsertedEvent); insertWatcher.Start(); WqlEventQuery removeQuery = new WqlEventQuery("SELECT * FROM __InstanceDeletionEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'"); ManagementEventWatcher removeWatcher = new ManagementEventWatcher(removeQuery); removeWatcher.EventArrived += new EventArrivedEventHandler(DeviceRemovedEvent); removeWatcher.Start(); // Do something while waiting for events System.Threading.Thread.Sleep(20000000); } 
+40
Oct 17 '13 at 19:41
source share

Adding VitalyB to the message.

To create an event in which ANY USB device is installed, use the following:

 var watcher = new ManagementEventWatcher(); var query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2"); watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived); watcher.Query = query; watcher.Start(); 

This will trigger an event when a USB device is connected. It even works with DAQ National Instruments, which I'm trying to automatically detect.

+18
Dec 11 '12 at 18:23
source share

Answer VitalyB does not close the removal of the device. I changed it a bit to trigger the event, both when setting the insert and as well as the code to get the drive letter of the inserted media.

 using System; using System.Management; namespace MonitorDrives { class Program { public enum EventType { Inserted = 2, Removed = 3 } static void Main(string[] args) { ManagementEventWatcher watcher = new ManagementEventWatcher(); WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_VolumeChangeEvent WHERE EventType = 2 or EventType = 3"); watcher.EventArrived += (s, e) => { string driveName = e.NewEvent.Properties["DriveName"].Value.ToString(); EventType eventType = (EventType)(Convert.ToInt16(e.NewEvent.Properties["EventType"].Value)); string eventName = Enum.GetName(typeof(EventType), eventType); Console.WriteLine("{0}: {1} {2}", DateTime.Now, driveName, eventName); }; watcher.Query = query; watcher.Start(); Console.ReadKey(); } } } 
+14
Feb 23 '16 at 21:22
source share

You can also use WMI to detect insert events. This is a bit more complicated than monitoring WM_CHANGEDEVICE messages, but it does not require a window handle, which can be useful if you are running in the background as a service.

+5
Mar 06 '09 at 21:50
source share

Edit all of the above answers a bit:

 using System.Management; public partial class MainForm : Form { public MainForm() { InitializeComponent(); bgwDriveDetector.DoWork += bgwDriveDetector_DoWork; bgwDriveDetector.RunWorkerAsync(); } private void DeviceInsertedEvent(object sender, EventArrivedEventArgs e) { string driveName = e.NewEvent.Properties["DriveName"].Value.ToString(); MessageBox.Show(driveName + " inserted"); } private void DeviceRemovedEvent(object sender, EventArrivedEventArgs e) { string driveName = e.NewEvent.Properties["DriveName"].Value.ToString(); MessageBox.Show(driveName + " removed"); } void bgwDriveDetector_DoWork(object sender, DoWorkEventArgs e) { var insertQuery = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2"); var insertWatcher = new ManagementEventWatcher(insertQuery); insertWatcher.EventArrived += DeviceInsertedEvent; insertWatcher.Start(); var removeQuery = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 3"); var removeWatcher = new ManagementEventWatcher(removeQuery); removeWatcher.EventArrived += DeviceRemovedEvent; removeWatcher.Start(); } } 
+5
May 10 '17 at 17:49
source share
+4
Mar 06 '09 at 19:48
source share

Here's what we did with C # .Net 4.0 in a WPF application. We are still looking for the answer to the question "how to indicate what type of device was inserted / removed", but this is the start:

  using System.Windows.Interop; ... public partial class MainWindow : Window { ... public MainWindow() { ... } //============================================================ // WINDOWS MESSAGE HANDLERS // private const int WM_DEVICECHANGE = 0x0219; // int = 537 private const int DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004; /// <summary> /// /// </summary> /// <param name="e"></param> protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); HwndSource source = PresentationSource.FromVisual(this) as HwndSource; source.AddHook(WndProc); } private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == WM_DEVICECHANGE) { ReadDongleHeader(); } return IntPtr.Zero; } } 
+3
Apr 6 2018-11-11T00:
source share
 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Management; using System.ComponentModel; namespace ConsoleApplication4 { public class usbState { public usbState() { } private void DeviceInsertedEvent(object sender, EventArrivedEventArgs e) { ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"]; foreach (var property in instance.Properties) { Console.WriteLine(property.Name + " = " + property.Value); } } private void DeviceRemovedEvent(object sender, EventArrivedEventArgs e) { ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"]; foreach (var property in instance.Properties) { Console.WriteLine(property.Name + " = " + property.Value); } } public void bgwDriveDetector_DoWork(object sender, DoWorkEventArgs e) { WqlEventQuery insertQuery = new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'"); ManagementEventWatcher insertWatcher = new ManagementEventWatcher(insertQuery); insertWatcher.EventArrived += new EventArrivedEventHandler(DeviceInsertedEvent); insertWatcher.Start(); WqlEventQuery removeQuery = new WqlEventQuery("SELECT * FROM __InstanceDeletionEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'"); ManagementEventWatcher removeWatcher = new ManagementEventWatcher(removeQuery); removeWatcher.EventArrived += new EventArrivedEventHandler(DeviceRemovedEvent); removeWatcher.Start(); } } class Class1 { private static void Main(string[] args) { usbState usb= new usbState(); BackgroundWorker bgwDriveDetector = new BackgroundWorker(); bgwDriveDetector.DoWork += usb.bgwDriveDetector_DoWork; bgwDriveDetector.RunWorkerAsync(); bgwDriveDetector.WorkerReportsProgress = true; bgwDriveDetector.WorkerSupportsCancellation = true; // System.Threading.Thread.Sleep(100000); Console.ReadKey(); } } } 
0
Apr 15 '19 at 13:13
source share



All Articles