在Windows SDK有一个CLI工具名为computerhardwareids
该工具将返回不同的GUID来选择特定的情况下,适当的硬件ID。
这是返回在我的电脑这个工具的输出:
Using the BIOS to gather information
Computer Information
--------------------
BIOS Vendor: American Megatrends Inc.
BIOS Version string: 1201
System BIOS Major Release: 4
System BIOS Minor Release: 6
System Manufacturer: To be filled by O.E.M.
System Family: To be filled by O.E.M.
System ProductName: To be filled by O.E.M.
SKU Number: SKU
Enclosure Type: 03 "Desktop"
Hardware IDs
------------
{a8670b03-1d98-5e95-ad4e-c64211eac9df} <- Manufacturer + Family + ProductName + SKUNumber + BIOS Vendor + BIOS Version + BIOS Major Release + BIOS Minor Release
{01c6b2a2-a2b2-58e4-906d-4677639f1a42} <- Manufacturer + Family + ProductName + BIOS Vendor + BIOS Version + BIOS Major Release + BIOS Minor Release
{dc5af3fe-c2de-539d-aafd-5061a1634723} <- Manufacturer + ProductName + BIOS Vendor + BIOS Version + BIOS Major Release + BIOS Minor Release
{d78b474d-dee0-5412-bc9d-e9f7d7783df2} <- Manufacturer + Family + ProductName + SKUNumber
{7ccbb6f1-9641-5f84-b00d-51ff218a4066} <- Manufacturer + Family + ProductName
{5a127cba-be28-5d3b-84f0-0e450d266d97} <- Manufacturer + SKUNumber
{6525c6e5-28e9-5f9c-abe4-20fd82504002} <- Manufacturer + ProductName
{6525c6e5-28e9-5f9c-abe4-20fd82504002} <- Manufacturer + Family
{482f3f58-6045-593a-9be4-611717ce4770} <- Manufacturer + Enclosure Type
{11b4a036-3b64-5421-a372-22c07df10a4d} <- Manufacturer
我想开发应该模仿微软工具的功能,一个通用的使用功能, 正好返回相同HardwareIds(完全一样)。
我发现的信息在MSDN上,所有的输出似乎很记录,它包含有关返回此工具的价值的信息,但它并没有明确指定WMI类的属性,它只是说,“BIOS”和“ 系统 ” :
· ComputerHardwareIds概述
· 指定硬件ID为计算机
我很失落,我找不到任何数值,如“家庭”,“BIOS供应商”,“BIOS主要版本”,“BIOS次要版本”,我不知道在哪里的“SKU数”是指。
我觉得这些都是WMI类,其中工具获得的所有数据,使GUID的一部分:
· Win32_BIOS类可以
· Win32_BaseBoard类
· Win32_ComputerSystem类
· Win32_ComputerSystemProduct类
请注意,文档还这样说:
然后,每个串被转换成通过使用SHA-1散列算法GUID。
这就是我一直试图做的,但我不知道我是否错了一些概念或一些值,它是不完整的,我也有与图形用户界面(与commentlines解释)的问题:
Private Function GetHardwareId() As Guid
Dim HardwareId As String = String.Empty
Dim BIOSVersion, BIOSVendor, BIOSMajorRelease, BIOSMinorRelease,
SystemManufacturer, SystemFamily, SystemProductName, SKUNumber As String
' Get System Info.
Using wmi As New Management.ManagementObjectSearcher("select * from Win32_ComputerSystem")
Using SystemInfo As Management.ManagementObject = wmi.Get(0)
SystemManufacturer = Convert.ToString(SystemInfo.Properties("Manufacturer").Value)
SystemProductName = Convert.ToString(SystemInfo.Properties("Model").Value)
SystemFamily = I don't know how to get it.
SKUNumber = I don't know how to get it.
End Using
End Using
' Get BIOS Info.
Using wmi As New Management.ManagementObjectSearcher("select * from Win32_BIOS")
Using BIOSInfo As Management.ManagementObject = wmi.Get(0)
BIOSVersion = Convert.ToString(BIOSInfo.Properties("SMBIOSBIOSVersion").Value)
BIOSVendor = I don't know how to get it.
BIOSMajorRelease = I don't know how to get it.
BIOSMinorRelease = I don't know how to get it.
End Using
End Using ' wmi
HardwareId = BIOSVersion & BIOSVendor & BIOSMajorRelease & BIOSMinorRelease &
SystemManufacturer & SystemFamily & SystemProductName & SKUNumber
' Here I call other method to encode the resulting string to SHA1 Hash
HardwareId = ConvertToSHA1(HardwareId)
' and then continue below...
' But this will not work,
' it throws an exception about missing "-" chars in the SHA1 string.
' So Microsoft formats "manualy" the SHA1 string to add some "-"?
Return Guid.Parse(HardwareId)
End Function
要生成,你需要从SMBIOS(通常使用GetSystemFirmwareTable)的值相同的GUID,然后使用“&”字符加入他们的行列。 确保字符串用UTF-16编码。 然后,您需要使用5型(SHA-1)UUID生成方案与70ffd812-4c7f-4c7d-0000-000000000000作为命名空间。
我不认为你的问题是可以解决你所希望的方式。 但也有没有理由,尚未。
MS从提供的各种数据的SHA散列产生确定性的GUID。 如果根据创建rfc422标准其中包括4名定义GUID的命名空间中的一个,我们应该能够从使用这些4名的命名空间中的一个相同的数据重新创建GUID。
然而,)我不能和b) MSDN的“指定的硬件ID的电脑”中指出: the hardware ID for the computer must be produced by the ComputerHardwareIds tool (ComputerHardwareIDs.exe)...
。 这使我相信他们使用专有的方法(盐,私人密钥等)或定义自己的命名空间来产生这些。
一些解答您的辅助/子问题:
- BIOS版本/发布-按照DTMF.org规范,表5在偏移“释放”&H14和H15与和比“版本”不同。 然而,它们也可以嵌入在名称,标题,描述和SoftwareElementID性质
Win32_BIOS
(见下面的工具)。 这也似乎在被卷起Win32_BIOS.BiosVersion(1)
但它是相同的名称/标题等。
我觉得有点好奇,我们的系统是几年相隔,但具有相同的释放值,它可能指的是SMBIOS发布/规格。
SKU:根据MSDN,这是AKA IdentificationCode
家庭:在BIOS编码显然一部分,但WMI不公开或返回它(吗?)。
这同样适用于产品名称真, Model
你从其他地方获取可能只是巧合具有相同的值。
因此,它不会出现在哈希使用的值都暴露出来。 在我的旧系统,家庭和SKU为空。 其结果是,它似乎在第一和第二ID应该是相同的,但事实并非如此。
我不知道这是什么意思了,或者它们是如何看重的平均应用程序如果GUID / ID只能从该工具。 你可能会拨开周围的SDK的其他部分,看是否有组件或如提供在运行时的信息。
如果你只是想认识你看到它的下一次系统或设备,你可以根据rfc422,以确保您定义的命名空间中的唯一值的非常相同的“可能性非常高”简单地写你自己的方法。 要做到这一点,就像MS的唯一原因是,如果你要看到价值来自其它地方,这是情况并非如此。
最后,我没有理会张贴GUID制造商,因为你想要的东西无论如何也不会做的。
WMI助手获取属性值:
Public Sub GetWMIInfo(wmiclass As String)
Using searcher As New Management.ManagementObjectSearcher("select * from " & wmiclass)
For Each item As System.Management.ManagementObject In searcher.Get
DebugProperties(item)
Next
End Using
End Sub
' this sub is copied from the watcher answer I gave:
Private Sub DebugProperties(mo As Management.ManagementObject)
For Each pd As PropertyData In mo.Properties
If pd.Value IsNot Nothing Then
' some props are string arrays, so you can iterate them if you want
Console.WriteLine("{0} {1}", pd.Name,
If(pd.Value IsNot Nothing,
pd.Value.ToString,
"Nothing"))
End If
Next
End Sub
输出是这样的:
Caption BIOS Date: XXXXXXXXXXXX Ver: 04.06.04
Description BIOS Date: ##/##/## 11:18:49 Ver: 04.06.04
Manufacturer Dell Inc.
Name BIOS Date: ##/##/## 11:18:49 Ver: 04.06.04
PrimaryBIOS True
ReleaseDate ########000000.000000+000
SerialNumber ######
SMBIOSBIOSVersion A##
SMBIOSMajorVersion #
SMBIOSMinorVersion #
public ArrayList<String> getWinVendor()
throws SecurityException, IOException,
NullPointerException, IndexOutOfBoundsException,
UnsupportedEncodingException {
try {
Process processProduct = Runtime.getRuntime().exec(new String[]{"wmic", "csproduct", "get", "vendor"});
processProduct.getOutputStream().close();
BufferedReader output = getOutput(processProduct);
BufferedReader error = getError(processProduct);
StringProductList = new ArrayList<String>();
String line = "", result = "";
while ((line = output.readLine()) != null) {
if (!line.toLowerCase().startsWith("vendor") && line.length() > 0) {
result = getSubStringSubstractEmptyAndTabSpace(line);
if (result.length() > 0) {
StringProductList.add(result);
} else {
StringProductList.add(UNKNOWN);
}
}
}
if (!StringProductList.isEmpty()) {
return StringProductList;
}
} catch (Exception e) {
if (e instanceof SecurityException
|| e instanceof IOException
|| e instanceof NullPointerException
|| e instanceof IndexOutOfBoundsException
|| e instanceof UnsupportedEncodingException) {
e.printStackTrace();
}
}
return null;
}
public BufferedReader getError(Process process) throws SecurityException, IOException,
NullPointerException, IndexOutOfBoundsException, UnsupportedEncodingException {
try {
if (getCmdEncoding() != null) {
return new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
}
} catch (Exception e) {
if (e instanceof SecurityException
|| e instanceof IOException
|| e instanceof NullPointerException
|| e instanceof IndexOutOfBoundsException) {
e.printStackTrace();
}
}
return new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
}
public BufferedReader getOutput(Process process) throws SecurityException, IOException,
NullPointerException, IndexOutOfBoundsException, UnsupportedEncodingException {
try {
if (getCmdEncoding() != null) {
return new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
}
} catch (Exception e) {
if (e instanceof SecurityException
|| e instanceof IOException
|| e instanceof NullPointerException
|| e instanceof IndexOutOfBoundsException) {
e.printStackTrace();
}
}
return new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
}
public static String getSubStringSubstractEmptyAndTabSpace(String word)
throws NullPointerException, IndexOutOfBoundsException {
if (word.length() > 0) {
try {
int length = word.length();
int start = 0, end = length;
for (int stringCharacter = 0; stringCharacter < length; stringCharacter++) {
char c = word.charAt(stringCharacter);
if (c == ' ' || c == '\t') {
start++;
} else {
stringCharacter = length;
}
}
for (int stringCharacter = length - 1; stringCharacter >= 0; stringCharacter--) {
char c = word.charAt(stringCharacter);
if (c == ' ' || c == '\t') {
end--;
} else {
stringCharacter = -1;
}
}
if (start == length) {
return "";
}
if (end == 0) {
return "";
}
if (start <= length - 1 && end >= 0) {
return word.substring(start, end);
}
} catch (Exception e) {
if (e instanceof NullPointerException
|| e instanceof IndexOutOfBoundsException) {
e.printStackTrace();
}
}
}
return word;
}