调用 DriveInfo.GetDrives() 可获取系统所有已挂载并分配盘符的逻辑驱动器数组,包括硬盘分区、U盘、SD卡、光驱等;它仅返回 Windows 卷信息,不区分物理设备,也不提供USB接口标识。

怎么用 DriveInfo.GetDrives() 拿到所有盘符
直接调用 DriveInfo.GetDrives() 就能拿到当前系统里所有逻辑驱动器的数组,包括硬盘分区、U盘、SD卡、光驱等。它不区分物理设备,只看 Windows 已挂载并分配了盘符的卷。
常见错误是以为它能“过滤出U盘”,其实不能——返回的每个 DriveInfo 对象只包含 Name(如 "D:\")、DriveType(如 DriveType.Removable)、IsReady 等字段,没有 USB 厂商、接口类型等信息。
- 必须检查
drive.DriveType == DriveType.Removable才可能对应U盘,但注意:部分USB移动硬盘会被识别为DriveType.Fixed - 务必判断
drive.IsReady,否则访问未就绪的U盘(比如刚插上还没初始化完)会抛IOException -
DriveInfo.GetDrives()是即时快照,不监听热插拔;要响应U盘插入/拔出,得配合WM_DEVICECHANGE或ManagementEventWatcher
为什么 DriveType.Removable 不等于“一定是U盘”
Windows 对 DriveType 的判定依赖底层存储类驱动报告的设备能力,而 USB 协议栈和厂商固件行为不统一。比如:
- 某些 USB 3.0 移动硬盘使用 UASP 模式后,被识别为
DriveType.Fixed(模拟本地磁盘) - 部分读卡器 + SD 卡组合也返回
Removable,但它不是U盘 - 虚拟光驱、网络映射盘、BitLocker 加密卷可能干扰判断
所以仅靠 DriveType 做唯一依据不可靠。真要区分U盘,得结合 WMI 查询 Win32_DiskDrive 的 InterfaceType 字段是否为 "USB",但这需要管理员权限且速度慢。
遍历驱动器时怎么避开权限错误和空盘符
有些驱动器(如光驱无盘、加密卷未解锁、BitLocker 锁定盘)在调用 DriveInfo.TotalSize 或 AvailableFreeSpace 时会直接抛异常,不是 IsReady == false 就能拦住的。
- 永远先判断
drive.IsReady,再访问容量、文件系统等属性 - 对
TotalSize、AvailableFreeSpace、RootDirectory等敏感属性访问加try/catch (IOException) - 跳过
drive.Name为"A:\"或"B:\"的老式软驱(虽然现在极少见,但GetDrives()仍可能返回) - 避免用
drive.RootDirectory.FullName当路径拼接起点——它末尾自带反斜杠,重复拼接易出"D:\\folder"
C# 示例:安全获取可读写的U盘盘符列表
下面这段代码只取 Removable 类型、已就绪、且能成功读取容量的盘符:
var usbDrives = new List<string>();
foreach (var drive in DriveInfo.GetDrives())
{
if (drive.DriveType != DriveType.Removable || !drive.IsReady) continue;
<pre class='brush:php;toolbar:false;'>try
{
// 触发一次轻量访问,确认真正可用
var _ = drive.TotalSize;
usbDrives.Add(drive.Name.TrimEnd('\'));
}
catch (IOException)
{
// 忽略无法访问的移除设备(如带密码的加密U盘)
continue;
}} // usbDrives 现在包含类似 ["E:", "F:"] 的字符串
这个逻辑绕开了 WMI、不依赖外部工具、也不要求高权限,适合基础场景。但要注意:它无法区分 USB 设备和蓝牙存储、PCMCIA 卡等其他可移动介质——如果业务强依赖“USB 接口”这个事实,就得上 WMI 了。
真正麻烦的从来不是列出来几个盘符,而是你没法靠一个 API 确认“这玩意插在 USB 口上、没加密、没写保护、驱动正常、且用户有权限读写”。每层抽象都在藏坑,得一层层试过去。



















