在.NET 6的C#中获取指定U盘的PID、VID及序列号方法咨询
在.NET 6中获取指定U盘的PID、VID和序列号
问题分析
你之前用Win32_PnPEntity查询的方式无法直接关联U盘的盘符或名称,因为该类实例和逻辑盘符没有直接绑定关系。要实现按盘符/名称精准筛选U盘,需要通过WMI的多个类关联查询:Win32_DiskDrive(USB磁盘设备)→ Win32_DiskPartition(磁盘分区)→ Win32_LogicalDisk(逻辑盘符),同时从Win32_DiskDrive的属性中提取PID、VID和序列号。
实现步骤
- 安装
System.ManagementNuGet包(.NET 6需手动安装,框架默认不包含) - 定义存储U盘信息的实体类
- 编写WMI关联查询逻辑,获取所有U盘的完整信息(含盘符、名称、VID、PID、序列号)
- 实现按盘符/名称筛选指定U盘的方法
完整代码示例
1. 安装NuGet包
在项目中执行以下命令:
Install-Package System.Management
或通过NuGet包管理器搜索安装。
2. U盘信息实体类
public class UsbDriveInfo { // 盘符(如D:) public string DriveLetter { get; set; } // 设备名称(如USB Mass Storage Device) public string DeviceName { get; set; } // 厂商ID(VID) public string Vid { get; set; } // 产品ID(PID) public string Pid { get; set; } // 设备序列号 public string SerialNumber { get; set; } }
3. 获取所有U盘信息并筛选的核心代码
using System.Management; using System.Text.RegularExpressions; using System.Linq; public static class UsbDriveHelper { // 获取所有U盘的完整信息 public static List<UsbDriveInfo> GetAllUsbDrives() { var usbDrives = new List<UsbDriveInfo>(); // 第一步:查询所有USB接口的磁盘驱动器 var diskDriveSearcher = new ManagementObjectSearcher( "SELECT * FROM Win32_DiskDrive WHERE InterfaceType='USB'"); foreach (var diskDrive in diskDriveSearcher.Get()) { var deviceName = diskDrive["Caption"]?.ToString(); var pnpDeviceId = diskDrive["PNPDeviceID"]?.ToString(); var serialNumber = diskDrive["SerialNumber"]?.ToString()?.Trim(); // 从PNPDeviceID提取VID和PID var vidPidMatch = Regex.Match(pnpDeviceId ?? "", @"VID_([0-9A-Fa-f]{4})&PID_([0-9A-Fa-f]{4})"); var vid = vidPidMatch.Groups[1].Value; var pid = vidPidMatch.Groups[2].Value; // 第二步:关联磁盘分区 var partitionSearcher = new ManagementObjectSearcher( $"ASSOCIATORS OF {{Win32_DiskDrive.DeviceID='{diskDrive["DeviceID"]}'}} WHERE AssocClass=Win32_DiskDriveToDiskPartition"); foreach (var partition in partitionSearcher.Get()) { // 第三步:关联逻辑盘符 var logicalDiskSearcher = new ManagementObjectSearcher( $"ASSOCIATORS OF {{Win32_DiskPartition.DeviceID='{partition["DeviceID"]}'}} WHERE AssocClass=Win32_LogicalDiskToPartition"); foreach (var logicalDisk in logicalDiskSearcher.Get()) { var driveLetter = logicalDisk["DeviceID"]?.ToString(); usbDrives.Add(new UsbDriveInfo { DriveLetter = driveLetter, DeviceName = deviceName, Vid = vid, Pid = pid, SerialNumber = serialNumber }); } } } return usbDrives; } // 按盘符筛选指定U盘 public static UsbDriveInfo GetUsbDriveByLetter(string driveLetter) { if (string.IsNullOrEmpty(driveLetter)) return null; // 统一格式为大写带冒号,如D: var normalizedLetter = driveLetter.Trim().ToUpper(); if (!normalizedLetter.EndsWith(":")) normalizedLetter += ":"; return GetAllUsbDrives().FirstOrDefault(d => d.DriveLetter == normalizedLetter); } // 按设备名称筛选指定U盘(支持模糊匹配) public static UsbDriveInfo GetUsbDriveByName(string name) { if (string.IsNullOrEmpty(name)) return null; return GetAllUsbDrives().FirstOrDefault(d => !string.IsNullOrEmpty(d.DeviceName) && d.DeviceName.Contains(name, StringComparison.OrdinalIgnoreCase)); } }
4. 使用示例
// 获取所有U盘 var allUsbDrives = UsbDriveHelper.GetAllUsbDrives(); foreach (var drive in allUsbDrives) { Console.WriteLine($"盘符:{drive.DriveLetter}"); Console.WriteLine($"名称:{drive.DeviceName}"); Console.WriteLine($"VID:{drive.Vid}"); Console.WriteLine($"PID:{drive.Pid}"); Console.WriteLine($"序列号:{drive.SerialNumber}"); Console.WriteLine("---"); } // 按盘符获取指定U盘 var targetDrive = UsbDriveHelper.GetUsbDriveByLetter("D:"); if (targetDrive != null) { Console.WriteLine($"找到目标U盘:VID={targetDrive.Vid}, PID={targetDrive.Pid}, 序列号={targetDrive.SerialNumber}"); // 此处可用于生成加密狗密钥 }
注意事项
- 程序需要足够权限访问WMI信息,部分系统可能需要以管理员身份运行
- 部分U盘可能未返回
SerialNumber(取决于设备固件),需做空值处理 PNPDeviceID格式可能因设备略有差异,正则表达式已兼容常见格式- 多分区U盘会返回所有分区的盘符信息,可根据需求调整逻辑
内容的提问来源于stack exchange,提问作者Worst Noob
相关产品推荐
相关产品推荐

