.NET WinForms中获取已连接USB设备的型号名称
嘿,我刚好有两个实用的方案能帮你搞定WinForms里获取USB设备列表及型号的需求,不管是用WMI还是更底层的SetupAPI都能实现,我给你详细拆解下:
方案一:使用WMI(简单易上手)
WMI是Windows管理规范,用它来获取设备信息代码量少,不需要调用复杂的系统API,很适合快速开发。
步骤说明:
- 首先在你的WinForms项目里添加对
System.Management程序集的引用(右键项目→添加→引用→找到System.Management勾选) - 定义一个简单的类来存储USB设备信息:
public class UsbDeviceInfo { public string DeviceName { get; set; } public string Model { get; set; } public string DeviceId { get; set; } }
- 编写获取USB设备的方法:
using System.Management; public List<UsbDeviceInfo> GetUsbDevicesViaWmi() { var usbDevices = new List<UsbDeviceInfo>(); // 查询所有USB类的即插即用设备 var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE PNPClass='USB'"); foreach (var device in searcher.Get()) { var usbDevice = new UsbDeviceInfo(); // 获取设备名称 usbDevice.DeviceName = device["Name"]?.ToString(); // 获取型号(有些设备可能在Description或Model属性里,这里多做几个判断) usbDevice.Model = device["Description"]?.ToString() ?? device["Model"]?.ToString() ?? "未知型号"; // 获取设备ID,用于精准匹配特定设备 usbDevice.DeviceId = device["DeviceID"]?.ToString(); usbDevices.Add(usbDevice); } return usbDevices; }
- 在WinForms里调用这个方法,比如按钮点击事件:
private void btnGetUsbDevices_Click(object sender, EventArgs e) { var devices = GetUsbDevicesViaWmi(); // 把设备信息绑定到DataGridView展示 dataGridView1.DataSource = devices; // 或者判断是否存在特定设备 bool hasTargetDevice = devices.Any(d => d.Model.Contains("你的目标设备型号关键词")); MessageBox.Show(hasTargetDevice ? "已连接目标USB设备!" : "未检测到目标USB设备"); }
注意点:
- 有些USB设备的型号可能存储在不同的属性里,你可以根据实际设备调整属性名称(比如
Caption、Description等) - WMI的查询速度可能略慢,如果需要实时监控设备插拔,可能需要结合WMI事件监听
方案二:使用SetupAPI(底层更精准)
如果WMI获取的信息不够全,或者你需要更底层的设备细节,可以用Windows的SetupAPI,它能直接和设备管理器交互,获取更准确的设备属性。
代码示例:
首先定义需要的API调用和结构体(这些是Windows API的封装):
using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; public class UsbDeviceHelper { // 设备类GUID,这里是USB设备类的GUID private static readonly Guid GuidUsbClass = new Guid("{88BAE032-5A81-49f0-BC3D-A4FF138216D6}"); [DllImport("setupapi.dll", SetLastError = true)] private static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, uint Enumerator, IntPtr hwndParent, uint Flags); [DllImport("setupapi.dll", SetLastError = true)] private static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, uint MemberIndex, ref SP_DEVINFO_DATA DeviceInfoData); [DllImport("setupapi.dll", SetLastError = true)] private static extern bool SetupDiGetDeviceRegistryProperty(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, uint Property, out uint PropertyRegDataType, StringBuilder PropertyBuffer, uint PropertyBufferSize, out uint RequiredSize); [DllImport("setupapi.dll", SetLastError = true)] private static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet); [StructLayout(LayoutKind.Sequential)] private struct SP_DEVINFO_DATA { public uint cbSize; public Guid ClassGuid; public uint DevInst; public IntPtr Reserved; } private const uint DIGCF_PRESENT = 0x00000002; private const uint SPDRP_FRIENDLYNAME = 0x0000000C; // 友好名称 private const uint SPDRP_DEVICEDESC = 0x00000000; // 设备描述(型号相关) private const uint SPDRP_HARDWAREID = 0x00000001; // 硬件ID public static List<UsbDeviceInfo> GetUsbDevicesViaSetupApi() { var usbDevices = new List<UsbDeviceInfo>(); IntPtr deviceInfoSet = IntPtr.Zero; try { // 获取当前存在的USB设备集合 deviceInfoSet = SetupDiGetClassDevs(ref GuidUsbClass, 0, IntPtr.Zero, DIGCF_PRESENT); if (deviceInfoSet == IntPtr.Zero) return usbDevices; SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA(); deviceInfoData.cbSize = (uint)Marshal.SizeOf(typeof(SP_DEVINFO_DATA)); uint index = 0; // 枚举所有USB设备 while (SetupDiEnumDeviceInfo(deviceInfoSet, index, ref deviceInfoData)) { var usbDevice = new UsbDeviceInfo(); // 获取设备友好名称 usbDevice.DeviceName = GetDeviceProperty(deviceInfoSet, ref deviceInfoData, SPDRP_FRIENDLYNAME); // 获取设备描述(作为型号) usbDevice.Model = GetDeviceProperty(deviceInfoSet, ref deviceInfoData, SPDRP_DEVICEDESC) ?? "未知型号"; // 获取硬件ID,用于精准匹配 usbDevice.DeviceId = GetDeviceProperty(deviceInfoSet, ref deviceInfoData, SPDRP_HARDWAREID); usbDevices.Add(usbDevice); index++; } } finally { if (deviceInfoSet != IntPtr.Zero) SetupDiDestroyDeviceInfoList(deviceInfoSet); } return usbDevices; } private static string GetDeviceProperty(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, uint propertyId) { StringBuilder sb = new StringBuilder(1024); uint requiredSize = 0; uint regDataType = 0; if (SetupDiGetDeviceRegistryProperty(deviceInfoSet, ref deviceInfoData, propertyId, out regDataType, sb, (uint)sb.Capacity, out requiredSize)) { return sb.ToString(); } return null; } }
然后在WinForms里调用这个方法,和WMI的方式类似:
private void btnGetUsbDevicesSetupApi_Click(object sender, EventArgs e) { var devices = UsbDeviceHelper.GetUsbDevicesViaSetupApi(); dataGridView1.DataSource = devices; bool hasTarget = devices.Any(d => d.Model.Equals("目标设备型号", StringComparison.OrdinalIgnoreCase)); MessageBox.Show(hasTarget ? "目标设备已连接!" : "未找到目标设备"); }
优势:
- 能获取更精准的设备属性,尤其是一些WMI没暴露的细节
- 枚举速度比WMI快,适合对性能有要求的场景
不管你选哪种方案,都能轻松实现获取USB设备列表并判断特定设备是否连接的需求,你可以根据自己的项目需求来选择~
内容的提问来源于stack exchange,提问作者VivaLebowski
相关产品推荐
相关产品推荐

