在C# .NET Framework应用中如何获取连接PC的SD卡盘符
如何在C# .NET Framework应用中获取连接到PC的SD卡的盘符
问题描述
我已经查阅了该主题下的相关推荐问题,但均未找到符合需求的解决方案。
目前尝试的方案存在以下问题:
- 使用
System.IO.DriveInfo.GetDrives()或者搭配查询语句Win32_LogicalDisk的System.Management.ManagementObjectSearcher(),可以获取所有设备的盘符,但无法区分哪个是SD卡设备 - 使用查询条件为
Caption = 'SDHC Card'的CIM_LogicalDevice查询的ManagementObjectSearcher(),可以获取2个Caption属性为SDHC Card的设备,但无法得到对应的盘符信息
补充说明
我可以手动从CIM_LogicalDisk查询结果中通过VolumeName属性确认SD卡对应的逻辑盘符,也可以从CIM_LogicalDevice查询结果中通过Name、Caption、Model属性确认SD卡对应的物理设备,但程序无法自动识别二者的对应关系。
需要注意的是,盘符和PHYSICALDRIVE编号的对应关系不是固定的,会随着不同可移动设备的插拔发生变化,需要在代码中实现逻辑盘与物理盘的自动对应关联。
已尝试的代码
using System; using System.Management; namespace Code3 { class Program { static void Main(string[] args) { Console.WriteLine("\tfrom: 'ManagementObjectSearcher()' with query \"Win32_LogicalDisk\""); var searcher1 = new ManagementObjectSearcher(@"\root\cimv2", "SELECT * FROM Win32_LogicalDisk"); foreach (ManagementBaseObject disk in searcher1.Get()) { string diskID = disk.GetPropertyValue("DeviceID").ToString(); int driveType = Convert.ToInt32(disk.GetPropertyValue("DriveType")); string diskCaption = disk.GetPropertyValue("Caption").ToString(); string diskDescription = disk.GetPropertyValue("Description").ToString(); string diskName = disk.GetPropertyValue("Name").ToString(); int diskMediaType = Convert.ToInt32(disk.GetPropertyValue("MediaType")); Console.WriteLine($"{diskName} - ID: {diskID}, Caption: {diskCaption}, Desc.: {diskDescription,-16}, Drive Type: {driveType}, Media Type: {diskMediaType}."); } Console.WriteLine(); Console.WriteLine("\tfrom: 'ManagementObjectSearcher()' with query SelectQuery(\"CIM_LogicalDevice\", \"Caption = 'SDHC Card'\")"); ManagementScope mgmtScope = new ManagementScope(@"\root\cimv2"); SelectQuery devQuery = new SelectQuery("CIM_LogicalDevice", "Caption = 'SDHC Card'"); var searcher2 = new ManagementObjectSearcher(mgmtScope, devQuery); foreach (ManagementBaseObject device in searcher2.Get()) { Console.WriteLine($"{device.GetPropertyValue("Name"),-15} - Caption: {device.GetPropertyValue("Caption")}, Device ID: {device.GetPropertyValue("DeviceID")}."); continue; // ... to skip property display if (!string.IsNullOrEmpty(device.GetPropertyValue("Name").ToString())) { PropertyDataCollection props = device.Properties; Console.WriteLine($"\n\t\tProperties of {device.GetPropertyValue("DeviceID")} Drive: \n"); foreach (var prop in device.Properties) { if (prop.Value != null) Console.WriteLine($"{prop.Name,-20} - {prop.Type,-8} - {prop.Value ?? "(null)"}"); } Console.WriteLine(); } } Console.ReadKey(); } } }
解决方案
通过WMI的关联类串联物理磁盘、磁盘分区、逻辑盘符三层关系,结合SD卡的设备特征筛选即可实现需求,完整实现代码如下:
using System; using System.Collections.Generic; using System.Management; namespace SdCardDetector { class Program { static void Main(string[] args) { List<string> sdCardDrives = GetSdCardDriveLetters(); Console.WriteLine("检测到的SD卡盘符:"); foreach (string drive in sdCardDrives) { Console.WriteLine(drive); } Console.ReadKey(); } static List<string> GetSdCardDriveLetters() { List<string> result = new List<string>(); // 筛选SD卡物理磁盘,可根据自己设备的属性调整关键词 string[] sdKeywords = { "SD", "SDHC", "SDXC", "Secure Digital", "读卡器", "Card Reader" }; // 第一步:遍历所有物理磁盘 using (var diskSearcher = new ManagementObjectSearcher(@"root\cimv2", "SELECT * FROM Win32_DiskDrive")) { foreach (ManagementObject disk in diskSearcher.Get()) { string caption = disk["Caption"]?.ToString() ?? ""; string model = disk["Model"]?.ToString() ?? ""; bool isSdDisk = false; foreach (string keyword in sdKeywords) { if (caption.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0 || model.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0) { isSdDisk = true; break; } } if (!isSdDisk) continue; // 第二步:关联查询该物理磁盘对应的分区 string partitionQuery = $"ASSOCIATORS OF {{Win32_DiskDrive.DeviceID='{disk["DeviceID"]?.ToString().Replace("\\", "\\\\")}'}} WHERE AssocClass=Win32_DiskDriveToDiskPartition"; using (var partitionSearcher = new ManagementObjectSearcher(partitionQuery)) { foreach (ManagementObject partition in partitionSearcher.Get()) { // 第三步:关联查询分区对应的逻辑盘符 string logicalDiskQuery = $"ASSOCIATORS OF {{Win32_DiskPartition.DeviceID='{partition["DeviceID"]}'}} WHERE AssocClass=Win32_LogicalDiskToPartition"; using (var logicalSearcher = new ManagementObjectSearcher(logicalDiskQuery)) { foreach (ManagementObject logicalDisk in logicalSearcher.Get()) { string driveLetter = logicalDisk["DeviceID"]?.ToString(); if (!string.IsNullOrEmpty(driveLetter) && !result.Contains(driveLetter)) { result.Add(driveLetter); } } } } } } } return result; } } }
注意事项
- 使用前需要在项目引用中添加
System.Management程序集 - 如果设备识别不准确,可以打印所有
Win32_DiskDrive的Caption和Model属性,调整筛选关键词即可 - 支持多读卡器/多SD卡同时接入的场景,会返回所有符合条件的盘符
内容的提问来源于stack exchange,提问作者JNygrenLT
相关产品推荐
相关产品推荐

