Получите идентификаторы оборудования, как Microsoft
В Windows SDK есть инструмент CLI, который называется computerhardwareids.
Инструмент возвращает различные идентификаторы GUID для выбора правильного HardwareId для конкретного случая.
Это вывод, который возвращает этот инструмент на моем ПК:
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
Я хотел бы разработать общую функцию использования, которая должна имитировать функциональность этого инструмента Microsoft, возвращая точно такие же аппаратные идентификаторы (точно такие же).
Я нашел информацию в MSDN, все выходные данные кажутся очень документированными и содержат информацию о значениях, которые возвращает этот инструмент, но он не определяет точно, какие свойства у классов WMI, он просто говорит "Bios" и "System":
· Указание идентификаторов оборудования для компьютера
Я очень растерялся, я не могу найти какие-либо значения, такие как "Семейство", "Поставщик BIOS", "Основной выпуск Bios", "Незначительный выпуск Bios", и я не уверен, к чему относится "номер SKU".
Я думаю, что это классы WMI, где инструмент получает часть всех данных для создания руководства:
· Класс Win32_ComputerSystemProduct
Обратите внимание, что в документации также сказано это:
Затем каждая строка преобразуется в GUID с использованием алгоритма хеширования SHA-1.
Это то, что я пытался сделать, но я не уверен, ошибаюсь ли я с какой-то концепцией или какими-то ценностями, это неполно, и у меня также есть проблемы с Guis (объяснено с комментариями):
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
3 ответа
Чтобы сгенерировать те же GUID, вам нужно получить значения из SMBIOS (обычно используя GetSystemFirmwareTable), а затем соединить их, используя символ '&'. Убедитесь, что строки закодированы с помощью UTF-16. Затем необходимо использовать схему генерации UUID типа 5 (SHA-1) с 70ffd812-4c7f-4c7d-0000-000000000000 в качестве пространства имен.
Я не думаю, что ваша проблема может быть решена так, как вы хотите. Но пока также нет никаких причин для этого.
MS создает детерминированные GUID из SHA-хеша различных предоставленных данных. Если он создан в соответствии со стандартами rfc422, который включает одно из 4 определенных пространств имен GUID, мы сможем воссоздать GUID из тех же данных, используя одно из этих четырех пространств имен.
Тем не менее, а) я не могу и б) MSDN "Указание идентификаторов оборудования для компьютера" гласит: the hardware ID for the computer must be produced by the ComputerHardwareIds tool (ComputerHardwareIDs.exe)...
, Это наводит меня на мысль, что они используют собственный метод (Salt, закрытый ключ и т. Д.) Или определили свое собственное пространство имен для их генерации.
Некоторые ответы на ваши второстепенные / подвопросы:
- Версия / выпуск BIOS - в соответствии со спецификацией DTMF.org Таблица 5 "Выпуск" по смещению - &H14 и &H15 и отличается от "Версия". Однако они также могут быть встроены в свойства Name, Caption, Description и SoftwareElementID
Win32_BIOS
(см. инструмент ниже). Это также, кажется, спрятано вWin32_BIOS.BiosVersion(1)
но это то же самое, что имя / подпись и т. д.
Мне немного любопытно, что наши системы разнесены на несколько лет, но имеют одинаковые значения Release, это может относиться к выпуску / спецификации SMBios.
SKU: Согласно MSDN, это АКА
IdentificationCode
Семейство: очевидно является частью кодировки BIOS, но WMI не раскрывает и не возвращает его (пока?).
То же самое относится и к наименованию продукта,
Model
Вы можете получить то же значение из другого места только по стечению обстоятельств.
Таким образом, кажется, что все значения, используемые в хэше, не отображаются. В моей старой системе Family и SKU не имеют значения. В результате кажется, что первый и второй идентификаторы должны совпадать, но это не так.
Я не уверен, для чего они предназначены или как они представляют большую ценность для среднего приложения, если GUID/ID доступен только из этого инструмента. Вы можете покопаться в других частях SDK, чтобы увидеть, есть ли сборки или что-то подобное, чтобы предоставить информацию во время выполнения.
Если вы просто захотите распознать систему или устройство в следующий раз, когда увидите это, вы можете просто написать свой собственный метод, основанный на rfc422, чтобы обеспечить ту же самую "очень высокую вероятность" уникального значения в определенном вами пространстве имен. Единственная причина сделать это так же, как MS, это то, что вы увидите, что это значение приходит откуда-то еще, а это не так.
Наконец, я не стал публиковать GUID maker, так как он все равно не будет делать то, что вы хотите.
Помощники 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;
}