WM_DEVICECHANGE消息是一个当电脑插入或者拔出其他设备时,发出的一个消息(如:usb,相机等)下面程序通过设备的GUID对WM_DEVICECHANGE进行详细操作,使其能获取更准确的消息。
创作不易。转载请附上原文链接
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace M400C
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
const int WM_DEVICECHANGE = 0x0219;
const int DBT_DEVICEARRIVAL = 0x8000;
const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
const int DBT_DEVTYP_DEVICEINTERFACE = 0x00000005;
const int DEVICE_NOTIFY_WINDOW_HANDLE = 0;
private static readonly Guid GuidDevinterfaceUSBDevice = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED");
[StructLayout(LayoutKind.Sequential)]
internal class DEV_BROADCAST_HDR
{
public int dbch_size;
public int dbch_devicetype;
public int dbch_reserved;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DEV_BROADCAST_DEVICEINTERFACE
{
public int dbcc_size;
public int dbcc_devicetype;
public int dbcc_reserved;
public Guid dbcc_classguid;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
public string dbcc_name;
}
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr RegisterDeviceNotification(IntPtr IntPtr, IntPtr NotificationFilter, Int32 Flags);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern uint UnregisterDeviceNotification(IntPtr hHandle);
public IntPtr hMainWnd = IntPtr.Zero;
private static IntPtr notificationHandle = IntPtr.Zero;
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
hMainWnd = new WindowInteropHelper(this).Handle;
HwndSource hwnd = HwndSource.FromHwnd(hMainWnd);
if (null != hwnd)
{
hwnd.AddHook(new HwndSourceHook(this.WndProc));
}
RegisterUsbDeviceNotification(hMainWnd);
}
protected IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_DEVICECHANGE)
{
if (lParam != IntPtr.Zero)
{
string sDeviceAction = string.Empty;
sDeviceAction = ((int)wParam == DBT_DEVICEARRIVAL) ? " insert!" : " remove!";
MessageBox.Show(sDeviceAction);
DEV_BROADCAST_DEVICEINTERFACE pdbch = (DEV_BROADCAST_DEVICEINTERFACE)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_DEVICEINTERFACE));
string sHardwareId = pdbch.dbcc_name;
sHardwareId.ToUpper();
//这可以依据pdbch.dbcc_name判断是什么usb设备里面的什么设备,
if((SHardwareID.Contains("设备的PID,VID如:"VID_0951&PID_1666"))
{
//表明是这种类型的设备在插拔
}
}
}
return IntPtr.Zero;
}
private void RegisterUsbDeviceNotification(IntPtr windowHandle)
{
DEV_BROADCAST_DEVICEINTERFACE deviceInterface = new DEV_BROADCAST_DEVICEINTERFACE();
int size = Marshal.SizeOf(deviceInterface);
deviceInterface.dbcc_size = size;
deviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
deviceInterface.dbcc_classguid = GuidDevinterfaceUSBDevice;
IntPtr buffer = default(IntPtr);
buffer = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(deviceInterface, buffer, true);
notificationHandle = RegisterDeviceNotification(hMainWnd, buffer, DEVICE_NOTIFY_WINDOW_HANDLE);
}
private void Window_Closed(object sender, EventArgs e)
{
if (notificationHandle != IntPtr.Zero)
{
UnregisterDeviceNotification(notificationHandle);
notificationHandle = IntPtr.Zero;
}
}
}
}
下面是微软官网的链接
https://docs.microsoft.com/en-us/windows/win32/api/dbt/ns-dbt-dev_broadcast_deviceinterface_a