111,094
社区成员




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