使用Windows服务和c#检测USB驱动器插入和删除

考虑制作USB分布式应用程序的可能性
将自动启动插入USB棒和closures时删除棒

将使用.Net和C#。
寻找build议如何处理这个使用C#?


更新:两个可能的解决scheme实现这个服务。
– 重写WndProc
要么
– 使用ManagementEventWatcher的WMI查询

你可以使用WMI,这很容易,它比WndProc解决scheme的服务更好。

这是一个简单的例子:

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

就是这样:)

这对我很好,再加上你可以find更多有关设备的信息。

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

添加到VitalyB的post。

要插入任何 USB设备插入的事件,请使用以下命令:

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

无论何时插入USB设备,都会引发事件。 它甚至可以与NI试图自动检测的NI DAQ一起使用。

VitalyB的答案不包括删除设备。 我改变了一下触发事件,当媒体插入删除 ,还代码获取插入媒体的驱动器号。

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

您还可以使用WMI来检测插入事件。 这比监视WM_CHANGEDEVICE消息要复杂一点,但是如果你在后台作为服务运行,它不需要窗口句柄。

尝试WM_CHANGEDEVICE处理。

这是我们在WPF应用程序下用C#.Net 4.0所做的。 我们仍然在寻找“如何判断哪个设备types被插入/删除”的答案,但这是一个开始:

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

上面所有的答案有点编辑:

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