插入USB时如何获得pid vid?

时间:2019-06-18 12:23:15

标签: c# usb pid

我在Visual Studio,Windows窗体应用程序中使用C#进行了编码。插入ıt时,我想查看USB的pid和vid。我写了这段代码,但是foreach (ManagementObject service in s.Get())中有错误。在s.Get()部分。它运行在Form1_Load部分,但卡在WNDProc中。

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    if(m.Msg == WM_DEVICECHANGE)
            switch ((int)m.WParam)
            {
                case DBT_DEVICEARRIVAL:
                    listBox1.Items.Add("New Device Connected");

                 ManagementObjectSearcher s = new ManagementObjectSearcher("@SELECT * FROM Win32_USBHub");

                foreach (ManagementObject service in s.Get())
                {

                    listBox1.Items.Add(service);
                }


                string[] ports = SerialPort.GetPortNames();

                Console.WriteLine("The following serial ports were found:");
                foreach (string port in ports)
                {
                    Console.WriteLine(port);
                    listBox1.Items.Add(port);
                 }

                 break;

                case DBT_DEVICEREMOVECOMPLETE:
                    listBox1.Items.Add("Device Removed");
                    break; 
}

1 个答案:

答案 0 :(得分:0)

主要问题是WM_DEVICECHANGE仅用于您注册的信息,只有少数例外,可以在RegisterDeviceNotification的备注中看到。

以下是您需要执行的详细操作:

要使用设备上的WM_DEVICECHANGEDBT_DEVICEARRIVAL来获取设备,您需要使用正确填充的RegisterDeviceNotification结构在user32.dll中调用名为DEV_BROADCAST_DEVICEINTERFACE_W的Win32 API。

如果操作正确,您将收到WM_DEVICECHANGE消息,其中包含DBT_DEVICEARRIVAL中所述的事件类型(在我们的情况下为Device Management Events)和详细信息的指针。指针需要读取为DEV_BROADCAST_HDR结构,从而可以识别这是否确实是DEV_BROADCAST_DEVICEINTERFACE_W结构。如果是这样,则此结构将包含一个名称,您需要对其进行解析,其中包含VID和PID。

要处理的事情很多,我花了几个小时才把它弄对。如果您需要快速解决方案,而无需执行可怕的细节,则将NuGet软件包Dapplo.Windows.Messages(VID和PID在0.9.7及更高版本中可用)添加到项目中。仅使用以下代码一次,否则您的代码将被多次调用,无需从Window进行此操作,但必须从Windows Forms或WPF应用程序进行此操作:

    var deviceNotificationSubscription = DeviceNotification
        .OnDeviceArrival()
        .Subscribe(deviceInterfaceChangeInfo => {
            // Your code goes here, and will be automatically called
            var vid = deviceInterfaceChangeInfo.Device.VendorId;
            var pid = deviceInterfaceChangeInfo.Device.ProductId;
        });

我的库高度依赖System.Reactive,在此不再赘述,这为您的应用程序提供了一种更实用的方法。您可以通过调用deviceNotificationSubscription.Dispose();来停止接收事件,该库将创建其自己的隐藏消息窗口以接收窗口消息,因此您甚至可以继续在后台接收信息。

Device property of the DeviceInterfaceChangeInfo具有DevBroadcastDeviceInterface结构,该结构包含原始Win32信息,但还具有一些更高级别的属性,例如:

  1. 从注册表中检索到的友好名称
  2. 设备类型,例如USB,HID等,包括IsUSB
  3. 供应商ID
  4. 产品ID
  5. 一个DeviceInterfaceClass枚举,可以更轻松地访问该类的代码
  6. 生成的URL,以获取有关设备的更多信息

让我知道这是否行得通,并且在您遇到任何问题时,在我的Dapplo.Windows GitHub项目上提出了问题!这个库中还有很多东西,但是不幸的是,大多数文档仍然需要编写。