监听USB设备插拔

复制代码
    /// <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);

 

posted @   罗曼蒂克'  阅读(75)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示