如何在.NET Core 2.1中获取USB存储设备序列号?
在.NET Core 2.1跨平台获取USB存储设备序列号
针对你遇到的.NET Core 2.1缺乏Windows注册表/WMI原生支持、又想跨平台且无需额外组件的需求,我们可以通过调用各操作系统原生命令的方式来实现——这和你熟悉的PowerShell思路类似,只不过在.NET里通过进程调用执行系统命令并解析输出,完全依赖系统自带工具,不用额外装任何东西。
核心思路
每个操作系统都有自带的硬件信息查询工具,我们在.NET中启动对应进程执行命令,捕获输出后解析出USB设备的序列号。这种方式完全利用系统原生能力,不需要安装第三方依赖。
分平台实现代码
下面是封装好的工具类,你可以直接复用:
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text.RegularExpressions; public class UsbSerialNumberHelper { public static List<string> GetUsbSerialNumbers() { var serialNumbers = new List<string>(); var osPlatform = Environment.OSVersion.Platform; switch (osPlatform) { case PlatformID.Win32NT: serialNumbers.AddRange(GetWindowsUsbSerials()); break; case PlatformID.Unix: // 区分Linux和macOS serialNumbers.AddRange(IsMacOS() ? GetMacOsUsbSerials() : GetLinuxUsbSerials()); break; default: throw new NotSupportedException($"当前操作系统 {osPlatform} 暂不支持"); } return serialNumbers.Where(s => !string.IsNullOrWhiteSpace(s)).ToList(); } private static List<string> GetWindowsUsbSerials() { var serials = new List<string>(); // 用Windows自带的wmic命令(无需额外安装PowerShell Core,兼容性更好) var processStartInfo = new ProcessStartInfo { FileName = "cmd.exe", Arguments = "/c \"wmic diskdrive where interfacetype='USB' get serialnumber\"", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using (var process = Process.Start(processStartInfo)) { process.WaitForExit(); var output = process.StandardOutput.ReadToEnd(); // 过滤掉标题行和空行 var lines = output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries) .Skip(1) .Select(l => l.Trim()); serials.AddRange(lines); } return serials; } private static List<string> GetLinuxUsbSerials() { var serials = new List<string>(); // 使用lsblk命令提取USB磁盘的serial字段 var processStartInfo = new ProcessStartInfo { FileName = "lsblk", Arguments = "-d -o SERIAL,TRAN | grep usb", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using (var process = Process.Start(processStartInfo)) { process.WaitForExit(); var output = process.StandardOutput.ReadToEnd(); var lines = output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { // 分割行提取serial(格式为" XXXXX usb") var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length >= 1) serials.Add(parts[0]); } } return serials; } private static List<string> GetMacOsUsbSerials() { var serials = new List<string>(); // 用diskutil命令获取外部磁盘的序列号 var processStartInfo = new ProcessStartInfo { FileName = "diskutil", Arguments = "info -all | grep -E '(Protocol:|Serial Number:|Device Node:)'", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using (var process = Process.Start(processStartInfo)) { process.WaitForExit(); var output = process.StandardOutput.ReadToEnd(); var lines = output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); string currentSerial = null; bool isUsbDevice = false; foreach (var line in lines) { if (line.StartsWith("Protocol:")) { isUsbDevice = line.Contains("USB"); } else if (line.StartsWith("Serial Number:")) { currentSerial = line.Split(new[] { ':' }, 2)[1].Trim(); } else if (line.StartsWith("Device Node:") && isUsbDevice && !string.IsNullOrEmpty(currentSerial)) { serials.Add(currentSerial); // 重置状态,处理下一个设备 currentSerial = null; isUsbDevice = false; } } } return serials; } private static bool IsMacOS() { // 通过系统版本字符串判断是否为macOS return Environment.OSVersion.VersionString.Contains("Darwin"); } }
使用示例
var usbSerials = UsbSerialNumberHelper.GetUsbSerialNumbers(); foreach (var serial in usbSerials) { Console.WriteLine($"USB设备序列号: {serial}"); }
注意事项
- 权限问题:Linux和macOS上,程序需要管理员权限(比如
sudo运行)才能读取完整的硬件信息,否则可能无法获取序列号。 - 命令兼容性:不同Linux发行版的
lsblk输出格式可能略有差异,如果遇到解析问题,可以调整分割逻辑;macOS的diskutil命令在各版本下输出格式基本稳定。 - Windows环境:
wmic命令是Windows系统自带的,无需额外安装任何组件,兼容性覆盖Win7及以上版本。
内容的提问来源于stack exchange,提问作者hdev
相关产品推荐
相关产品推荐

