简体   繁体   English

c#usb检测

[英]c# usb detection

We have several processes in the current Application. 我们在当前的应用程序中有几个进程。 One process handles about detection and removel of USB loader. 一个过程处理USB加载程序的检测和删除。 The code to handle detection and removal as below. 处理检测和删除的代码如下。

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

When i run the process which handles USB loader in the debug mode in the visual studio environment, it detects USB properly.but still i receive multiple messages. 当我在visual studio环境中运行以调试模式处理USB加载程序的过程时,它会正确检测USB。但我仍然会收到多条消息。 receives message with wparam value as "7" 3 times and then receives wparam value as "32768(0x8000/DBT_DEVICEARRIVAL )". 接收wparam值为“7”3次的消息,然后接收wparam值为“32768(0x8000 / DBT_DEVICEARRIVAL)”。 Is it normal? 这是正常的吗?

When i run all the other process along with the process which detects USB,it seems to be always the message with wparam value as "7" only received. 当我运行所有其他进程以及检测USB的进程时,似乎始终是仅接收到wparam值为“7”的消息。 receives meesage with wparam as "7" 5 times. 用wparam作为“7”5次接收meesage。 There is no message with wparam values as "(0x8000/DBT_DEVICEARRIVAL )". 没有wparam值为“(0x8000 / DBT_DEVICEARRIVAL)”的消息。 what could be the problem? 可能是什么问题呢?

Appreciate any inputs/solutions. 感谢任何输入/解决方案。

Regards Raju 问候Raju

From what I've seen, that's normal. 从我所看到的,这是正常的。 I run into exactly the same issue here. 我遇到了完全相同的问题。

Two things you can do - set a var for DateTime.Now and then check on the next arrival to see if time difference between the arrivals is less than x seconds from the last time there was an event (basically store the time from when you last handled an arrival) 你可以做两件事 - 为DateTime.Now设置一个var然后检查下一次到达,看看到达之间的时间差是否小于上次发生事件时的x秒(基本上存储了你上次的时间)处理到达)

or 要么

You can store the list of drives and if the event handles the same device as you already have, then you ignore it. 您可以存储驱动器列表,如果事件处理的设备与您已有的设备相同,则忽略它。

But yes, because USB devices often present themselves to the system as multiple devices, it tends to send multiple device insertions. 但是,是的,因为USB设备经常将自己作为多个设备呈现给系统,所以它往往会发送多个设备插入。

Another thing I've used to get around this is using WMI's events, with a watcher to detect logical storage events (__InstanceCreation with a target of Win32_LogicalDisk) 我用来解决这个问题的另一件事是使用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();
    }

With the EventArrived handler of... 使用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 ends up actually being the drive letter, such as D: or whatever... Drivename最终实际上是驱动器号,例如D:或者其他......

Downside of that is the app needs to run with the correct privileges for the local WMI scope and it's slightly more intensive than passively handling window messages. 缺点是应用程序需要使用本地WMI范围的正确权限运行,并且比被动处理窗口消息稍微强一些。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM