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

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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WinForm监听USB插拔可以通过使用System.Management命名空间中的ManagementEventWatcher类来实现。 首先,在WinForm应用程序中,添加对System.Management命名空间的引用。 然后,创建一个ManagementEventWatcher对象来监听USB设备插拔事件。可以使用以下代码示例: ```csharp using System; using System.Management; public class USBMonitor { private ManagementEventWatcher watcher; public event EventHandler<USBEventArgs> USBInserted; public event EventHandler<USBEventArgs> USBRemoved; public void StartMonitoring() { var query = new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'"); watcher = new ManagementEventWatcher(query); watcher.EventArrived += Watcher_EventArrived; watcher.Start(); } public void StopMonitoring() { if (watcher != null) { watcher.Stop(); watcher.Dispose(); watcher = null; } } private void Watcher_EventArrived(object sender, EventArrivedEventArgs e) { var usb = (ManagementBaseObject)e.NewEvent["TargetInstance"]; var usbEventArgs = new USBEventArgs(usb); if ((uint)usb["ConfigManagerErrorCode"] == 0) { USBInserted?.Invoke(this, usbEventArgs); } else { USBRemoved?.Invoke(this, usbEventArgs); } } } public class USBEventArgs : EventArgs { public ManagementBaseObject USBDevice { get; private set; } public USBEventArgs(ManagementBaseObject usbDevice) { USBDevice = usbDevice; } } ``` 在WinForm的代码中,可以初始化并启动USBMonitor类的实例,并订阅USBInserted和USBRemoved事件以处理插拔事件: ```csharp USBMonitor usbMonitor = new USBMonitor(); usbMonitor.USBInserted += UsbMonitor_USBInserted; usbMonitor.USBRemoved += UsbMonitor_USBRemoved; usbMonitor.StartMonitoring(); private void UsbMonitor_USBInserted(object sender, USBEventArgs e) { // 处理USB设备插入事件 ManagementBaseObject usbDevice = e.USBDevice; // ... } private void UsbMonitor_USBRemoved(object sender, USBEventArgs e) { // 处理USB设备拔出事件 ManagementBaseObject usbDevice = e.USBDevice; // ... } ``` 通过以上的代码,我们可以在WinForm应用程序中监听USB设备插拔事件,并进行相应的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值