C# implements detection of USB device plugging and unplugging (winform wpf)

The function of WndProc function in C# Winform:
Mainly used to intercept and process system messages and custom messages
for example:
Windows programs will generate a lot of messages. For example, when you click the mouse or move the window, messages will be generated. This function is the default message processing function. You can overload this function to develop your own message processing flow.
In a Winform program, the WndProc function can be rewritten to capture all window messages that occur.
In this way, we can “tamper” with incoming messages and artificially make the window change its behavior.
We use C# to implement the function of detecting USB disk insertion and removal by rewriting the C# WndProc function.

Reference https://www.cnblogs.com/peterYong/p/16208125.html
Simple test code:

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; //Add IO namespace
  
namespace CheckUdisk
{
    public partial class Form1 : Form
    {
  
        //Define constants
        public const int WM_DEVICECHANGE = 0x219;
        public const int DBT_DEVICEEARRIVAL = 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_DEVICEEARRIVAL:
                            DriveInfo[] s = DriveInfo.GetDrives();
                            foreach (DriveInfo drive in s)
                            {
                                if (drive.DriveType == DriveType.Removable)
                                {
                                    this.richTextBox1.AppendText("The USB flash drive has been inserted, the drive letter is " + drive.Name.ToString() + "\r\
");
                                    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 disk has been unmounted");
                            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)
            {
                // Removable storage device, not A drive
                if ((drive.DriveType == DriveType.Removable) & amp; & amp; false == drive.Name.Substring(0, 1).Equals("A"))
                {
                    Console.WriteLine("Found a USB flash drive: " + drive.Name);
                }
            }
        }


    }
}

WindowsAPI Example-C# Version_Monitor USB device plugging and unplugging

1. Winform code:
 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(@"
Device unplugged detected");
                        break;
                    case (int)HandleNotification_MessageWParam.DBT_DEVTYP_Arrival:
                        textBox1.AppendText(@"
Device plugged in detected");
                        break;
                }
            }
        }
    }
2. UsbNotification class:
using System;
using System.Runtime.InteropServices;
using static ZhiBiXiaobai.WindowAPIHelper.WindowsAPI_DeviceManagement;

namespace WinFormsApp1
{
    /// <summary>
    /// Monitor USB device insertion and removal
    /// </summary>
    public class UsbNotification
    {
        #region constant
        private static readonly Guid GuidDevinterfaceUSBDevice = new("A5DCBF10-6530-11D2-901F-00C04FB951ED"); // used as USB device label
        #endregion constants

        private static IntPtr notificationHandle; // notification handle (here is the window handle)

        /// <summary>
        /// Specify (register) a window to receive notifications when a USB device is inserted or unplugged.
        /// </summary>
        /// <param name="windowHandle">The window handle to receive notifications. </param>
        public static void RegisterUsbDeviceNotification(IntPtr windowHandle)
        {
            DEV_BROADCAST_DEVICEINTERFACE dbi = new() // Object that stores device information
            {
                dbch_devicetype = DEV_BROADCAST_DEVICEINTERFACE_Devicetype.DBT_DEVTYP_DEVICEINTERFACE, // The notification category is "device class"
                dbch_reserved = 0, // reserved and not used
                dbch_classguid = GuidDevinterfaceUSBDevice,
                dbch_name = '0'
            };
            dbi.dbch_size = Marshal.SizeOf(dbi); // Allocate memory to DevBroadcastDeviceinterface from the unmanaged memory of the process
            //IntPtr buffer = Marshal.AllocHGlobal(dbi.dbch_size); // Allocate memory to DevBroadcastDeviceinterface from the unmanaged memory of the process
            //Marshal.StructureToPtr(dbi, buffer, true); // Marshal data from managed objects to unmanaged memory blocks (dbi->buffer, delete old data)
            notificationHandle = RegisterDeviceNotification(windowHandle, dbi, 0);
        }

        /// <summary>
        /// Unregister USB device notification window
        /// </summary>
        public static void UnregisterUsbDeviceNotification()
        {
            UnregisterDeviceNotification(notificationHandle);
        }
    }
}
3. WindowsAPI class:

WindowsAPI-C# version_Common API for device management

4. HandleNotification_MessageMsg and HandleNotification_MessageWParam:

WindowsAPI-C# version_Summary of common notification types for handle callbacks (HandleNotification)

5. Supplement-WPF writing method:
 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); // Add method
                UsbNotification.RegisterUsbDeviceNotification(windowHandle);
            }
        }

        /// <summary>
        ///Hook execution method
        /// </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 + =(@"
Device unplugged detected");
                        break;
                    case (int)HandleNotification_MessageWParam.DBT_DEVTYP_Arrival:
                        lblT1.Content + = (@"
Device plugged in detected");
                        break;
                }
            }
            handled = false;
            return IntPtr.Zero;
        }
    }

Reference https://www.cnblogs.com/qq2806933146xiaobai/p/16899198.html