我有一些代码可以从 WMI 获取硬盘序列号。
SelectQuery selectQuery = new SelectQuery("Win32_PhysicalMedia");
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(selectQuery);
foreach (ManagementObject wmi_PM in searcher.Get())
{
string str = wmi_PM["SerialNumber"];
}
起初我认为它正在工作并检索到正确的序列号。在尝试使用它进行比较之后,我发现 WMI 报告的数字并不完全正确。WMI 序列号用一堆空格填充,并且字符被调换。
打印在贴纸上并由某些工具(可能使用 DeviceIoControl)返回的实际驱动器序列号是“3RH8B1BG”,但 WMI 返回“R38H1BGB”。
真实序列号:3RH8B1BG
WMI 序列号:R38H1BGB
一些工具,如 SiSoftware Sandra,返回这个填充和转置的数字,但它不是实际的序列号。如果您每隔一个位置调换一次,WMI 值就是序列号。这是正常的吗?我应该只编码以将其转换为正确的值吗?
我尽量避免使用 WMI,但现在似乎在网上搜索如何做某事都会带回 WMI 示例。
不同制造商的2个不同硬盘驱动器的WMI值序列号都被调换了,因此它不是一个磁盘。
更新:使用 DeviceIoControl 找到了一些代码
http://addressof.com/blog/archive/2004/02/14/392.aspx
令人惊讶的是,DeviceIoControl 也返回了一个转置的序列号。在上面 CorySmith 的代码中,它有一个 SwapChars 函数
Private Shared Function SwapChars(ByVal chars() As Char) As String
For i As Integer = 0 To chars.Length - 2 Step 2
chars.Reverse(chars, i, 2)
Next
Return New String(chars).Trim
End Function
他提到的 c++ 代码有翻转到:
// function to decode the serial numbers of IDE hard drives
// using the IOCTL_STORAGE_QUERY_PROPERTY command
char * flipAndCodeBytes (const char * str,
int pos,
int flip,
char * buf)
{
...
}
猜这是 DeviceIoControl 和 WMI 的标准,不敢相信我遇到的任何其他解决方案或示例都没有这个。