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 値は、1 つおきに転置した場合のシリアル番号です。これは正常ですか?それを正しい値に転置するようにコーディングする必要がありますか?
私は 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 の標準だと思いますが、私が遭遇した他のソリューションや例にはこれがなかったとは信じられません。