Unity 2020.3获取硬盘序列号遇NotImplementedException问题求助
Unity 2020.3 获取硬盘序列号解决方案
问题原因
System.Management的WMI接口在Unity的Mono运行时环境中未被完整实现,直接引用该dll会触发未实现异常——这是因为Unity搭载的Mono并非完整.NET框架,对WMI相关API支持有限。
可行解决方案
方案1:调用Windows原生命令行(仅Windows平台)
通过执行wmic diskdrive get serialnumber命令获取序列号,无需依赖System.Management.dll,兼容性更强。
代码示例:
using System.Diagnostics; using System.Text; public string GetHarddiskSerial() { string serialNumber = string.Empty; Process process = new Process(); ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = "wmic.exe", Arguments = "diskdrive get serialnumber", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true, StandardOutputEncoding = Encoding.UTF8 }; process.StartInfo = startInfo; process.Start(); string output = process.StandardOutput.ReadToEnd(); process.WaitForExit(); // 解析输出提取有效序列号 string[] lines = output.Split(new[] { '\n', '\r' }, System.StringSplitOptions.RemoveEmptyEntries); if (lines.Length >= 2) { serialNumber = lines[1].Trim(); } return serialNumber; }
注意事项:
- 仅适用于Windows平台,打包后需确保程序有执行cmd命令的权限
- 多硬盘场景会返回所有硬盘序列号,可添加筛选逻辑,比如
diskdrive where MediaType='Fixed hard disk media' get serialnumber筛选内置硬盘
方案2:存储首次获取的序列号(跨平台兼容思路)
若不需要实时读取硬盘序列号,仅需设备唯一标识,可在首次运行时用方案1获取序列号,存入PlayerPrefs后续直接读取:
public string GetDeviceUniqueId() { string uniqueId = PlayerPrefs.GetString("DeviceHarddiskSerial"); if (string.IsNullOrEmpty(uniqueId)) { uniqueId = GetHarddiskSerial(); // 调用方案1的方法 PlayerPrefs.SetString("DeviceHarddiskSerial", uniqueId); PlayerPrefs.Save(); } return uniqueId; }
方案3:跨平台实现(支持Windows/Mac/Linux)
针对不同平台调用对应系统命令,实现跨平台获取:
public string GetPlatformSerialNumber() { #if UNITY_WIN return GetHarddiskSerial(); // 方案1的Windows实现 #elif UNITY_STANDALONE_OSX return GetMacSerial(); #elif UNITY_STANDALONE_LINUX return GetLinuxSerial(); #else return SystemInfo.deviceUniqueIdentifier; // Unity内置设备唯一标识,可替代硬盘序列号 #endif } // Mac平台获取硬盘序列号 private string GetMacSerial() { string serial = string.Empty; Process process = new Process(); process.StartInfo.FileName = "/usr/sbin/system_profiler"; process.StartInfo.Arguments = "SPStorageDataType"; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.UseShellExecute = false; process.Start(); string output = process.StandardOutput.ReadToEnd(); process.WaitForExit(); int index = output.IndexOf("Serial Number:"); if (index != -1) { serial = output.Substring(index + 15).Trim().Split('\n')[0]; } return serial; } // Linux平台获取硬盘序列号 private string GetLinuxSerial() { string serial = string.Empty; Process process = new Process(); process.StartInfo.FileName = "lsblk"; process.StartInfo.Arguments = "-no serial"; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.UseShellExecute = false; process.Start(); string output = process.StandardOutput.ReadToEnd(); process.WaitForExit(); string[] lines = output.Split(new[] { '\n' }, System.StringSplitOptions.RemoveEmptyEntries); foreach (string line in lines) { string trimmed = line.Trim(); if (!string.IsNullOrEmpty(trimmed)) { serial = trimmed; break; // 取第一块硬盘序列号 } } return serial; }
关键说明
- 不要尝试在Unity中使用System.Management.dll获取硬盘序列号,Mono运行时不支持相关WMI API
- 命令行调用的方法需确保打包后程序有对应权限执行命令
- 若仅需设备唯一标识,Unity内置的
SystemInfo.deviceUniqueIdentifier是更简便的跨平台选择,它基于硬件信息生成,但并非硬盘序列号
内容的提问来源于stack exchange,提问作者Deuterium
相关产品推荐
相关产品推荐

