隐藏

C#实现检测USB设备的插拔( winform wpf)

发布:2024/5/5 21:12:23作者:管理员 来源:本站 浏览次数:417

C# Winform中WndProc 函数作用:

主要用在拦截并处理系统消息和自定义消息

比如:

windows程序会产生很多消息,比如你单击鼠标,移动窗口都会产生消息。这个函数就是默认的消息处理函数。你可以重载这个函数来制定自己的消息处理流程.

在Winform程序中,可以重写WndProc函数,来捕捉所有发生的窗口消息。

这样,我们就可以"篡改"传入的消息,而人为的让窗口改变行为。

我们用C#实现检测U盘插拔的功能,是用重写C# WndProc函数来做到的。


参考 https://www.cnblogs.com/peterYong/p/16208125.html

简单测试代码:



   using System;  

   using System.Collections.Generic;  

   using System.ComponentModel;  

   using System.Data;  

   using System.Drawing;  

   using System.Linq;  

   using System.Text;  

   using System.Threading.Tasks;  

   using System.Windows.Forms;  

   using System.IO;  //添加IO命名空间  

     

   namespace CheckUdisk  

   {  

       public partial class Form1 : Form  

       {  

     

           //定义常量  

           public const int WM_DEVICECHANGE = 0x219;  

           public const int DBT_DEVICEARRIVAL = 0x8000;  

           public const int DBT_CONFIGCHANGECANCELED = 0x0019;  

           public const int DBT_CONFIGCHANGED = 0x0018;  

           public const int DBT_CUSTOMEVENT = 0x8006;            

           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 Form1()  

           {  

               InitializeComponent();  

           }  

     

           private void Form1_Load(object sender, EventArgs e)  

           {  

     

           }  

     

           protected override void WndProc(ref Message m)  

           {  

     

               try  

               {  

                   if (m.Msg == WM_DEVICECHANGE)  

                   {  

                       switch (m.WParam.ToInt32())  

                       {  

                           case WM_DEVICECHANGE:  

                               break;  

                           case DBT_DEVICEARRIVAL:  

                               DriveInfo[] s = DriveInfo.GetDrives();  

                               foreach (DriveInfo drive in s)  

                               {  

                                   if (drive.DriveType == DriveType.Removable)  

                                   {  

                                       this.richTextBox1.AppendText("U盘已插入,盘符是" + drive.Name.ToString() + "\r\n");  

                                       break;  

                                   }  

                               }  

                               break;  

                           case DBT_CONFIGCHANGECANCELED:  

                               MessageBox.Show("2");  

                               break;  

                           case DBT_CONFIGCHANGED:  

                               MessageBox.Show("3");  

                               break;  

                           case DBT_CUSTOMEVENT:  

                               MessageBox.Show("4");  

                               break;  

                           case DBT_DEVICEQUERYREMOVE:  

                               MessageBox.Show("5");  

                               break;  

                           case DBT_DEVICEQUERYREMOVEFAILED:  

                               MessageBox.Show("6");  

                               break;  

                           case DBT_DEVICEREMOVECOMPLETE:  

                               this.richTextBox1.AppendText("U盘已卸载");  

                               break;  

                           case DBT_DEVICEREMOVEPENDING:  

                               MessageBox.Show("7");  

                               break;  

                           case DBT_DEVICETYPESPECIFIC:  

                               MessageBox.Show("8");  

                               break;  

                           case DBT_DEVNODES_CHANGED:  

                               MessageBox.Show("9");  

                               break;  

                           case DBT_QUERYCHANGECONFIG:  

                               MessageBox.Show("10");  

                               break;  

                           case DBT_USERDEFINED:  

                               MessageBox.Show("11");  

                               break;  

                           default:  

                               break;  

                       }  

                   }  

               }  

               catch (Exception ex)  

               {  

                   MessageBox.Show(ex.Message);  

               }  

     

               base.WndProc(ref m);  

           }  

   

   

   private void ScanDisk()

           {

               DriveInfo[] drives = DriveInfo.GetDrives();

               foreach (var drive in drives)

               {

                   // 可移动存储设备,且不是A盘

                   if ((drive.DriveType == DriveType.Removable) && false == drive.Name.Substring(0, 1).Equals("A"))

                   {

                       Console.WriteLine("找到一个U盘:" + drive.Name);

                   }

               }

           }

   

   

       }  

   }  


WindowsAPI示例-C#版_监控usb设备插拔

1、Winform代码:


       public partial class USBDeviceMode : Form

       {

           public USBDeviceMode()

           {

               InitializeComponent();

               UsbNotification.RegisterUsbDeviceNotification(this.Handle);

           }

           private void RFIDReaderMode_Load(object sender, EventArgs e)

           {

   

           }

           protected override void WndProc(ref Message m)

           {

               base.WndProc(ref m);

               if (m.Msg == (int)HandleNotification_MessageMsg.DBT_DEVTYP_DEVICEINTERFACE_Msg)

               {

                   switch ((int)m.WParam)

                   {

                       case (int)HandleNotification_MessageWParam.DBT_DEVTYP_Removecomplete:

                           textBox1.AppendText(@"

   检测到有设备拔出");

                           break;

                       case (int)HandleNotification_MessageWParam.DBT_DEVTYP_Arrival:

                           textBox1.AppendText(@"

   检测到有设备插入");

                           break;

                   }

               }

           }

       }


2、UsbNotification类:


   using System;

   using System.Runtime.InteropServices;

   using static ZhiBiXiaobai.WindowAPIHelper.WindowsAPI_DeviceManagement;

   

   namespace WinFormsApp1

   {

       /// <summary>

       /// 监听USB设备插拔

       /// </summary>

       public class UsbNotification

       {

           #region 常量

           private static readonly Guid GuidDevinterfaceUSBDevice = new("A5DCBF10-6530-11D2-901F-00C04FB951ED"); // 用作USB设备标签

           #endregion 常量

   

           private static IntPtr notificationHandle;  // 通知句柄(这里给窗口句柄)

   

           /// <summary>

           /// 指定(注册)一个窗口,以便在USB设备插入或拔出时接收通知。

           /// </summary>

           /// <param name="windowHandle">接收通知的窗口句柄。</param>

           public static void RegisterUsbDeviceNotification(IntPtr windowHandle)

           {

               DEV_BROADCAST_DEVICEINTERFACE dbi = new()  // 存储设备信息的对象

               {

                   dbch_devicetype = DEV_BROADCAST_DEVICEINTERFACE_Devicetype.DBT_DEVTYP_DEVICEINTERFACE,  // 通知类别为“设备的类”

                   dbch_reserved = 0,  // 保留不使用

                   dbch_classguid = GuidDevinterfaceUSBDevice,

                   dbch_name = '0'

               };

               dbi.dbch_size = Marshal.SizeOf(dbi);  // 从进程的非托管内存中给DevBroadcastDeviceinterface分配内存

               //IntPtr buffer = Marshal.AllocHGlobal(dbi.dbch_size);  // 从进程的非托管内存中给DevBroadcastDeviceinterface分配内存

               //Marshal.StructureToPtr(dbi, buffer, true);  // 将数据从托管对象封送到非托管内存块(dbi->buffer,删除旧的数据)

               notificationHandle = RegisterDeviceNotification(windowHandle, dbi, 0);

           }

   

           /// <summary>

           /// 注销USB设备通知窗口

           /// </summary>

           public static void UnregisterUsbDeviceNotification()

           {

               UnregisterDeviceNotification(notificationHandle);

           }

       }

   }


3、WindowsAPI类:


WindowsAPI-C#版_设备管理常用API

4、HandleNotification_MessageMsg与HandleNotification_MessageWParam:


WindowsAPI-C#版_句柄回调常用通知类型汇总(HandleNotification)

5、补充-WPF写法:


       public partial class MainWindow : Window

       {

           public MainWindow()

           {

               InitializeComponent();

           }

   

           protected override void OnSourceInitialized(EventArgs e)

           {

               base.OnSourceInitialized(e);

   

               HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);

               if (source != null)

               {

                   IntPtr windowHandle = source.Handle;

                   source.AddHook(HwndHandler);  // 添加方法

                   UsbNotification.RegisterUsbDeviceNotification(windowHandle);

               }

           }

   

           /// <summary>

           /// 钩子执行的方法

           /// </summary>

           private IntPtr HwndHandler(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)

           {

               if (msg == (int)HandleNotification_MessageMsg.DBT_DEVTYP_DEVICEINTERFACE_Msg)

               {

                   switch ((int)wParam)

                   {

                       case (int)HandleNotification_MessageWParam.DBT_DEVTYP_Removecomplete:

                           lblT1.Content+=(@"

   检测到有设备拔出");

                           break;

                       case (int)HandleNotification_MessageWParam.DBT_DEVTYP_Arrival:

                           lblT1.Content += (@"

   检测到有设备插入");

                           break;

                   }

               }

               handled = false;

               return IntPtr.Zero;

           }

       }


参考 https://www.cnblogs.com/qq2806933146xiaobai/p/16899198.html