如何通过COM号获取设备VID和PID

baidu_29905333 2015-09-18 04:26:29
想实现的功能是:1. 插入平板后,程序能自动检测到设备,获取设备的COM号。
2. 能获取该设备的VID和PID,并以此来过滤掉非该型号平板设备。

目前遇到的问题:第一点已经实现(请见下面的代码),现在就是不知道在下面代码框架下如何实现第二点。还请大神指点指点,不胜感激!

PS:下面的代码也是在网上找的,稍微修改了一下。

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

bool IsCopy = false;

public const Int32 WM_DEVICECHANGE = 0x219;
public const Int32 DBT_DEVICEARRIVAL = 0x8000;
public const Int32 DBT_DEVICEREMOVECOMPLETE = 0x8004;
public const Int32 DBT_DEVTYP_PORT = 0x00000003;

[StructLayout(LayoutKind.Sequential)]
public struct DEV_BROADCAST_HDR
{
public UInt32 dbch_size;
public UInt32 dbch_devicetype;
public UInt32 dbch_reserved;
}

protected override void WndProc(ref Message m)
{
if (m.Msg == WM_DEVICECHANGE)
{
switch (m.WParam.ToInt32())
{
// USB插上
case DBT_DEVICEARRIVAL:
if (!IsCopy) // 如果不用这个判断,会被多次调用,原因不明
{
DEV_BROADCAST_HDR dbhdr =
(DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LParam,
typeof(DEV_BROADCAST_HDR));

if (dbhdr.dbch_devicetype == DBT_DEVTYP_PORT)
{
IsCopy = true;

string portName =
Marshal.PtrToStringUni((IntPtr)(m.LParam.ToInt32()
+ Marshal.SizeOf(typeof(DEV_BROADCAST_HDR))));
}
}

break;

// USB移除
case DBT_DEVICEREMOVECOMPLETE:
IsCopy = false;
break;

default:
break;
}
}

base.WndProc(ref m);
}
...全文
1148 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
hmmvj575 2015-09-23
  • 打赏
  • 举报
回复
IntPtr pName = m.LParam + DEV_BROADCAST_DEVICEINTERFACEW.Size - sizeof(char); 这句话怎么通不过,提示错误,运算符“+”无法应用于"System.InPtr"和“int”类型的操作数。 求大神解答下
baidu_29905333 2015-09-21
  • 打赏
  • 举报
回复
十分以及非常感谢Forty2!
devmiao 2015-09-18
  • 打赏
  • 举报
回复
com调试助手看下就知道了。
Forty2 2015-09-18
  • 打赏
  • 举报
回复
COM和VID/PID没有必然的联系。因为COM是串口设备,而VID/PID是USB设备所有的。 当USB设备插入后,有些驱动程序可以把USB模拟为串口,而当虚拟串口被创建后,你本贴的代码收到DBT_DEVTYP_PORT通知,因此你得到了COM口信息。 DBT_DEVTYP_PORT不能让你直接得到USB的信息,你可以通过SetupDixxx系列的API来关联虚拟COM口和USB设备,然后得到USB的VID/PID,但是总的比较麻烦。 另一种‘比较’简单的方法是订阅USB设备通知。比如你可以订阅DBT_DEVTYP_DEVICEINTERFACE,并指定要求USB设备通知。但是,跟DBT_DEVTYP_PORT不一样的是,DBT_DEVTYP_DEVICEINTERFACE需要你显式地调用RegisterDeviceNotification。由于下例适用于各种USB设备,包括U盘,USB打印机等等,你可能需要用到达时间来关联USB设备和虚拟串口设备。 详细步骤见例子:

using System;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Load += delegate { RegisterUsbDeviceNotification(); };
            this.FormClosed += delegate { /* UnregisterDeviceNotification(cookie); */};
        }

        private void RegisterUsbDeviceNotification()
        {
            var filter = new DEV_BROADCAST_DEVICEINTERFACEW()
            {
                hdr = new DEV_BROADCAST_HDR() 
                {
                    dbch_Size = DEV_BROADCAST_DEVICEINTERFACEW.Size,
                    dbch_DeviceType = DBT_DEVTYP_DEVICEINTERFACE,
                },
                dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE
            };

            IntPtr cookie = RegisterDeviceNotification(  // 1
                this.Handle,
                ref filter,
                DEVICE_NOTIFY_WINDOW_HANDLE);
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_DEVICECHANGE)
            {
                switch (m.WParam.ToInt32())
                {
                    case DBT_DEVICEARRIVAL:
                        var hdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_HDR));
                        if (hdr.dbch_DeviceType == DBT_DEVTYP_DEVICEINTERFACE)
                        {
                            IntPtr pName = m.LParam + DEV_BROADCAST_DEVICEINTERFACEW.Size - sizeof(char);
                            string name = Marshal.PtrToStringUni(pName);  // 2
                            var match = Regex.Match(name, @"USB#VID_(?<vid>\w{4})&PID_(?<pid>\w{4})"); 
                            if (match.Success) \\ 3
                            {
                                this.Text = string.Format(
                                    "vid={0} pid={1}",
                                    match.Groups["vid"].Value,
                                    match.Groups["pid"].Value
                                    );
                            }
                        }
                        break;
                    case DBT_DEVICEREMOVECOMPLETE:
                        break;
                }
            }
            base.WndProc(ref m);
        }

        const int WM_DEVICECHANGE = 0x219;
        const int DBT_DEVICEARRIVAL = 0x00008000;
        const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
        const int DBT_DEVTYP_DEVICEINTERFACE = 0x00000005;
        const int DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000;
        static Guid GUID_DEVINTERFACE_USB_DEVICE = new Guid("{A5DCBF10-6530-11D2-901F-00C04FB951ED}");

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        static extern IntPtr RegisterDeviceNotification(
            IntPtr hRecipient,
            ref DEV_BROADCAST_DEVICEINTERFACEW NotificationFilter, 
            uint Flags);

        [StructLayout(LayoutKind.Sequential)]
        struct DEV_BROADCAST_HDR
        {
            public int dbch_Size;
            public int dbch_DeviceType;
            public int dbch_Reserved;
        }

        [StructLayout(LayoutKind.Sequential)]
        struct DEV_BROADCAST_DEVICEINTERFACEW
        {
            public DEV_BROADCAST_HDR hdr;
            public Guid dbcc_classguid;
            public char dbcc_name;
            public static readonly int Size = Marshal.SizeOf(typeof(DEV_BROADCAST_DEVICEINTERFACEW));
        }
    }
}
注释1:订阅通知,订阅那些DeviceInterface为USB_DEVICE的通知。 注释2:得到设备路径,类似\?\USB#VID_05AC&PID_1294&MI_00#0#{6bdd1fc6-810f-11d0-bec7-08002be2092f}。 注释3:VID和PID可以在USB的设备路径中得到。 资源: 关于RegisterDeviceNotification https://msdn.microsoft.com/zh-cn/library/windows/desktop/aa363431.aspx 关于DEV_BROADCAST_DEVICEINTERFACE https://msdn.microsoft.com/zh-cn/library/windows/desktop/aa363244.aspx 关于GUID_DEVINTERFACE_USB_DEVICE https://msdn.microsoft.com/zh-cn/library/windows/hardware/ff545972.aspx

111,094

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧