C#的USB检测USB

2023-09-03 16:50:29 作者:三岁就会撩汉

我们在目前的应用多道工序。一个进程处理有关检测USB装载机和removel。在code处理检测和删除如下图所示。

We have several processes in the current Application. One process handles about detection and removel of USB loader. 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;
            }
        }

当我运行它处理USB装载机在Visual Studio环境中调试模式的过程中,检测到USB properly.but我仍收到多封邮件。其中wParam值73次收到消息,然后接收WPARAM值32768(等于0x8000 / DBT_DEVICEARRIVAL)。它是正常的吗?

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. receives message with wparam value as "7" 3 times and then receives wparam value as "32768(0x8000/DBT_DEVICEARRIVAL )". Is it normal?

当我运行的所有其他进程以及其检测USB的过程中,似乎总是与WPARAM值7只接收到消息。其中wParam接收meesage为7的5倍。有其中wParam值没有任何消息(为0x8000 / DBT_DEVICEARRIVAL)。 可能是什么问题?

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. receives meesage with wparam as "7" 5 times. There is no message with wparam values as "(0x8000/DBT_DEVICEARRIVAL )". what could be the problem?

鸭preciate任何输入/解决方案。

Appreciate any inputs/solutions.

问候 拉朱

推荐答案

这是我所看到的,这是正常的。我碰到正好在这里同样的问题。

From what I've seen, that's normal. I run into exactly the same issue here.

有两件事情可以做 - 设置一个VAR为DateTime.Now然后检查接下来的到来,看看是否来港定居人士之间的时间差小于x秒从上一次有一个事件(主要储存从时间当你最后处理的到来)

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)

您可以存储驱动器的列表,如果事件处理相同的设备,你已经有了,那么你就忽略它。

You can store the list of drives and if the event handles the same device as you already have, then you ignore it.

但是,是的,因为USB设备通常present自身到系统中的多个设备,它往往会发送多个设备插入。

But yes, because USB devices often present themselves to the system as multiple devices, it tends to send multiple device insertions.

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

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)

    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处理程序

With the EventArrived handler of...

    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:或什么...

Drivename ends up actually being the drive letter, such as D: or whatever...

的下跌空间的应用程序需要与当地的WMI范围内正确的权限运行,这是稍微紧张的不是被动地处理窗口消息。

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.