c#usb检测

时间:2011-03-30 22:30:40

标签: c# .net 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)”的消息。 可能是什么问题?

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

此致 拉朱

1 个答案:

答案 0 :(得分:3)

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

你可以做两件事 - 为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范围的正确权限运行,并且比被动处理窗口消息稍微强一些。