c#usb检测

我们在当前的应用程序中有几个进程。 一个过程处理USB加载程序的检测和删除。 处理检测和删除的代码如下。

protected override void WndProc(ref Message m) { switch (m.Msg) { case Win32.WM_DEVICECHANGE: OnDeviceChange(ref m); break; } base.WndProc(ref m); } private void OnDeviceChange(ref Message msg) { int wParam = (int)msg.WParam; Win32.DEV_BROADCAST_VOLUME dbVol = new Win32.DEV_BROADCAST_VOLUME(); Win32.DEV_BROADCAST_HDR msgDevHeader = new Win32.DEV_BROADCAST_HDR(); const int DBT_DEVTYP_VOLUME = 0x00000002; string loaderUpdates; switch (wParam) { case Win32.DBT_DEVICEARRIVAL: int devType = Marshal.ReadInt32(msg.LParam, 4); if (devType == DBT_DEVTYP_VOLUME) { } break; case Win32.DBT_DEVICEREMOVECOMPLETE: break; } } 

当我在visual studio环境中运行以调试模式处理USB加载程序的过程时,它会正确检测USB。但我仍然会收到多条消息。 接收wparam值为“7”3次的消息,然后接收wparam值为“32768(0x8000 / DBT_DEVICEARRIVAL)”。 这是正常的吗?

当我运行所有其他进程以及检测USB的进程时,似乎始终是仅接收到wparam值为“7”的消息。 用wparam作为“7”5次接收meesage。 没有带有wparam值的消息为“(0x8000 / DBT_DEVICEARRIVAL)”。 可能是什么问题呢?

感谢任何输入/解决方案。

问候Raju

从我所看到的,这是正常的。 我遇到了完全相同的问题。

你可以做两件事 – 为DateTime.Now设置一个var,然后检查下一次到达,看看到达时间之间的时间差是否小于上次发生事件时的x秒(基本上存储了你上次的时间)处理到达)

要么

您可以存储驱动器列表,如果事件处理的设备与您已有的设备相同,则忽略它。

但是,是的,因为USB设备经常将自己作为多个设备呈现给系统,所以它往往会发送多个设备插入。

我用来解决这个问题的另一件事是使用WMI的事件,观察者检测逻辑存储事件(__InstanceCreation,目标为Win32_LogicalDisk)

  private void startMonitor() { while (serviceStarted) { ManagementEventWatcher watcher = new ManagementEventWatcher(); WqlEventQuery query = new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_LogicalDisk'"); watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived); watcher.Query = query; watcher.Start(); watcher.WaitForNextEvent(); } Thread.CurrentThread.Abort(); } 

使用EventArrived处理程序…

  private void watcher_EventArrived(object obj, EventArrivedEventArgs e) { var newEvent = e.NewEvent; ManagementBaseObject targetInstance = (ManagementBaseObject)newEvent.GetPropertyValue("TargetInstance"); string drivename = targetInstance.GetPropertyValue("Name").ToString(); 

Drivename最终实际上是驱动器号,例如D:或者其他……

缺点是应用程序需要使用本地WMI范围的正确权限运行,并且比被动处理窗口消息稍微强一些。