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

hmmvj575 2015-09-23 10:03:32
我的需求是这样的
描述:当USB设备插入电脑之后,通过VID和PID获取他的COM口是多少
问题:现在网上找一份源码,但是里面有些问题,请大神解答!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Management;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;

namespace 获取设备的VID__PID
{

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得到设备路径,类似\?\USB#VID_05AC&PID_1294&MI_00#0#{6bdd1fc6-810f-11d0-bec7-08002be2092f}。
var match = Regex.Match(name, @"USB#VID_(?<vid>\w{4})&PID_(?<pid>\w{4})");
if (match.Success) //3VID和PID可以在USB的设备路径中得到。
{
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));
}
}
}


中间的这句IntPtr pName = m.LParam + DEV_BROADCAST_DEVICEINTERFACEW.Size - sizeof(char);
是无法进行操作。请问怎么转换才好,
...全文
633 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
花开尽落轮回 2017-12-05
  • 打赏
  • 举报
回复
收藏一下 ,谢谢分享
tcmakebest 2015-09-23
  • 打赏
  • 举报
回复
何不直接监视COM口的插入和拔出消息, 网上应该有这个代码.
Forty2 2015-09-23
  • 打赏
  • 举报
回复
引用 楼主 hmmvj575 的回复:
...现在网上找一份源码...
引用 3 楼 hmmvj575 的回复:
已经实现了通过设备的VID和PID查找COM。 需要的加我QQ276607489 技术出售100元
得到社区帮助的时候,不妨想想是否回馈社区,帮助别人的时候也帮助自己。 另外,VID和PID是不能直接查到COM口的。 原因很容易反推:插入两个同样厂商同样型号的设备,他们的VID(厂商号)相同,PID(产品号)也相同,但将虚拟出两个COM口。
hmmvj575 2015-09-23
  • 打赏
  • 举报
回复
我是想通过VID和PID得到插入设备的COM口,这样用户就不用选择直接可以连接了。 网上都是C++的写法,完全看不懂。求C#的写法

110,535

社区成员

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

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

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