/// <summary> /// 监听USB设备插拔 /// </summary> public class UsbNotification { [DllImport("user32.dll")] public static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, UInt32 Flags); [DllImport("user32.dll")] public static extern bool UnregisterDeviceNotification(IntPtr hHandle); public const int WM_DEVICECHANGE = 0x219; //U盘插入后,OS的底层会自动检测到,然后向应用程序发送“硬件设备状态改变“的消息 public const int DBT_DEVICEARRIVAL = 0x8000; //就是用来表示U盘可用的。一个设备或媒体已被插入一块,现在可用。 public const int DBT_CONFIGCHANGECANCELED = 0x0019; //要求更改当前的配置(或取消停靠码头)已被取消。 public const int DBT_CONFIGCHANGED = 0x0018; //当前的配置发生了变化,由于码头或取消固定。 public const int DBT_CUSTOMEVENT = 0x8006; //自定义的事件发生。 的Windows NT 4.0和Windows 95:此值不支持。 public const int DBT_DEVICEQUERYREMOVE = 0x8001; //审批要求删除一个设备或媒体作品。任何应用程序也不能否认这一要求,并取消删除。 public const int DBT_DEVICEQUERYREMOVEFAILED = 0x8002; //请求删除一个设备或媒体片已被取消。 public const int DBT_DEVICEREMOVECOMPLETE = 0x8004; //一个设备或媒体片已被删除。 public const int DBT_DEVICEREMOVEPENDING = 0x8003; //一个设备或媒体一块即将被删除。不能否认的。 public const int DBT_DEVICETYPESPECIFIC = 0x8005; //一个设备特定事件发生。 public const int DBT_DEVNODES_CHANGED = 0x0007; //一种设备已被添加到或从系统中删除。 public const int DBT_QUERYCHANGECONFIG = 0x0017; //许可是要求改变目前的配置(码头或取消固定)。 public const int DBT_USERDEFINED = 0xFFFF; //此消息的含义是用户定义的 public const int DBT_DEVTYP_VOLUME = 0x00000002; /// <summary> /// 注册设备RegisterDeviceNotification-设备类型 /// </summary> [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct DEV_BROADCAST_DEVICEINTERFACE { public int dbcc_size; // 此结构的大小(以字节为单位)。 这是成员的大小加上 dbcc_name 字符串的实际长度 public int dbcc_devicetype; // 设置为 DBT_DEVTYP_DEVICEINTERFACE。 public int dbcc_reserved; // 保留值;请勿使用。 public Guid dbcc_classguid; // 接口设备类的 GUID。 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)] public string dbcc_name; // 一个以 null 结尾的字符串,指定设备的名称。 } public static void WndProc(ref Message m) { try { if (m.Msg == WM_DEVICECHANGE && m.LParam != IntPtr.Zero) { switch (m.WParam.ToInt32()) { case WM_DEVICECHANGE: MessageBox.Show("硬件设备状态改变"); break; case DBT_DEVICEARRIVAL: var camera = GetCameraSN(m.LParam); if (!string.IsNullOrWhiteSpace(camera)) { MessageBox.Show(camera + "相机已被插入,现在可用"); } MessageBox.Show(GetCameraSN(m.LParam) + "一个设备或媒体已被插入一块,现在可用"); break; case DBT_DEVICEREMOVECOMPLETE: MessageBox.Show(GetCameraSN(m.LParam) + "一个设备或媒体片已被移除"); break; case DBT_DEVNODES_CHANGED: Console.WriteLine("一种设备已被添加到或从系统中删除。"); break; } } } catch (Exception ex) { MessageBox.Show(ex.Message); } } private static string GetCameraSN(IntPtr lParm) { DEV_BROADCAST_DEVICEINTERFACE pdbch = (DEV_BROADCAST_DEVICEINTERFACE)Marshal.PtrToStructure(lParm, typeof(DEV_BROADCAST_DEVICEINTERFACE)); if (pdbch.dbcc_name.Contains("TSAM150A23B")) return Regex.Split(pdbch.dbcc_name, "#")[2]; else return null; } private static IntPtr notificationHandle; // 通知句柄(这里给窗口句柄) /// <summary> /// 指定(注册)一个窗口,以便在USB设备插入或拔出时接收通知。 /// </summary> /// <param name="windowHandle">接收通知的窗口句柄。</param> public static IntPtr RegisterUsbDeviceNotification(IntPtr windowHandle) { DEV_BROADCAST_DEVICEINTERFACE devInterface = new DEV_BROADCAST_DEVICEINTERFACE(); devInterface.dbcc_size = Marshal.SizeOf(devInterface); devInterface.dbcc_devicetype = 0x00000005; // DBT_DEVTYP_DEVICEINTERFACE devInterface.dbcc_reserved = 0; devInterface.dbcc_classguid = Guid.Empty; // 使用Guid.Empty来监听所有设备 IntPtr devInterfacePtr = Marshal.AllocHGlobal(devInterface.dbcc_size); Marshal.StructureToPtr(devInterface, devInterfacePtr, true); // 注册设备通知 notificationHandle = RegisterDeviceNotification(windowHandle, devInterfacePtr, 0x00000004); return notificationHandle; } /// <summary> /// 注销USB设备通知窗口 /// </summary> public static void UnregisterUsbDeviceNotification() { UnregisterDeviceNotification(notificationHandle); }
调用
UsbNotification.RegisterUsbDeviceNotification(this.Handle); UsbNotification.WndProc(ref m);
标签:插拔,const,USB,int,监听,DBT,dbcc,public,设备 From: https://www.cnblogs.com/aaaaq/p/18396848