当前位置: 首页 > 知识库问答 >
问题:

像微软一样获取硬件id

茅曾琪
2023-03-14

在Windows SDK中,有一个名为computerhardwareids的CLI工具

该工具返回各种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

我想开发一个通用使用函数,它应该模仿该Microsoft工具的功能,返回完全相同的硬件ID(完全相同)。

我在MSDN上找到了信息,所有的输出似乎都有详细的记录,它包含了关于返回这个工具的值的信息,但是它没有具体说明WMI类的属性,它只说了“Bios”和“System”:

计算机硬件概述

·指定计算机的硬件ID

我很迷茫,找不到任何“家族”、“Bios厂商”、“Bios主版本”、“BIOS次版本”之类的值,也不确定“SKU号”指的是哪里。

我认为这些是WMI类,工具在其中获取所有数据的一部分以制作guid:

Win32_BIOS类别

·Win32_BaseBoard类

·Win32_ComputerSystem类

·Win32_ComputerSystemProduct类

请注意,留档还说:

然后使用SHA-1散列算法将每个字符串转换为GUID。

这就是我尝试做的,但我不确定我是否错了某些概念或某些值,它不完整,而且我对 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个答案

马浩淼
2023-03-14
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;
}
卢俊发
2023-03-14

若要生成相同的 GUID,需要从 SMBIOS 获取值(通常使用 GetSystemFirmwareTable),然后使用”

亢雅懿
2023-03-14

我不认为你的问题可以按照你想要的方式解决。但到目前为止,也没有理由这样做。

MS正在根据所提供的各种数据的阿沙哈希创建确定性GUIDs。如果根据rfc422标准创建,其中包括4个已定义的GUID名称空间中的一个,我们应该能够使用这4个名称空间中的一个从相同的数据中重新创建GUID。

然而,a)我不能和b) MSDN的“为计算机指定硬件ID”声明:< code >计算机的硬件ID必须由计算机硬件ID工具(ComputerHardwareIds)产生...。这使我相信他们使用专有方法(Salt、私钥等)或定义自己的名称空间来生成这些。

对您的次要/次要问题的一些回答:

    < li>BIOS版本/发布-根据DTMF.org规范,表5“发布”是偏移

我觉得有点奇怪的是,我们的系统相隔几年,但具有相同的发布值,它可能指的是SMBios版本/规范。

> < li>

SKU:根据MSDN的说法,这就是< code>IdentificationCode

家族:显然是BIOS编码的一部分,但WMI不会公开或返回它(现在?)。

产品名称也是如此,您从其他地方获取的Model可能只是碰巧具有相同的值。

因此,哈希中使用的值似乎没有全部公开。在我的旧系统中,系列和SKU为空。因此,第一个ID和第二个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 #
 类似资料:
  • 问题内容: 我正在开发向用户介绍设备的应用程序。我在SO上遇到了许多问题,但没有找到答案。我想找到 型号编号 Android版 基带版本 内核版本 内部编号 我的手机的RAM。 对于此Thankx,我将不胜感激。 问题答案: 我在代码中使用了它,所以我把所有内容都放了:

  • 自我介绍 3min 问了一嘴本科非科班咋学了C++ 问实习内容,讲了一个你觉得值得讲的做的事情 10min kafka/异步回调 无报错不需调用抽帧,错了才需要调,那么如何通过错误排查过滤掉不需调用的任务 C++虚函数 5min 虚指针/虚表/内存分配 继承/多态 你在项目中用到了虚函数吗?怎么用的? C++和java的区别 5min jvm和C++内存泄漏 你怎么发现C++项目有没有delete

  • 我四处搜索,找到了一些有用的程序,例如: 但没人能帮我。我需要获得有关CPU、RAM、OS等的信息。有什么工具或程序可以帮助我吗?

  • 本文向大家介绍硬件和软件之间的差异。,包括了硬件和软件之间的差异。的使用技巧和注意事项,需要的朋友参考一下 硬件 硬件代表计算机的物理组件,例如其电子部件。例如,CPU,内存,硬盘,显示器,打印机,鼠标等。 软件 软件,代表在计算机系统上执行不同任务的程序。它是由CPU执行的编程代码,可以从键盘,鼠标等输入设备获取指令,并可以在监视器,打印机等输出设备上显示输出。例如MS Word,Google

  • 超级和蔼的面试官,说英语也很好听 1.自我介绍 2.介绍项目 3.项目相关问题 3.1 说一下缓存数据库不一致问题,你怎么解决的?为什么? 3.2 说一下redis的特点?支持多大的qps?延迟? 4. 算法题:LeetCode 200. 岛屿数量。 感觉微软考察重点就是算法题,自己用dfs啪一下做出来了,面试官让说说dfs的pros &amp; cons,答:快、简单,但有爆栈的可能。问怎么解决

  • 用teams技术面,面试官声音非常和蔼友善 无自我介绍,直接开始聊项目 挨个项目做简单介绍; 你在项目中遇到的哪些难点?怎么解决的? 跨端开发为什么要选flutter而不是RN? (说了一下自己对flutter发展历史和架构的理解) 之前工作中的开发和部署过程?(自测,内测,灰度,正式更新) RN和Flutter两者的效率谁更高,谁的size更大(平时没用过RN,没答上来) 在项目里怎么做前端性能