9月20日学习记录

通过下面的代码可以实现使用c++快速获得uuid:

使用chatgpt生成的:

cpp 复制代码
#include <WinSock2.h>
#include <windows.h>
#include <Wbemidl.h>
#include <iostream>
#include <DXGI.h>
#include <comdef.h>
#include <iostream>
#include <QDebug>
using namespace std;
#pragma comment(lib,"DXGI.lib")
#pragma warning(disable: 4996)
#pragma comment(lib, "wbemuuid.lib")

QString getMachineUUID()
{
    QString uuid = "";
    HRESULT hres = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
    if ((hres != RPC_E_TOO_LATE) && (hres != RPC_E_NO_GOOD_SECURITY_PACKAGES) && FAILED(hres))
    {
        qDebug() << "Failed to initialize security. "
            << "Error code = 0x"
            << hex << hres << endl;
        CoUninitialize();
        return uuid;
    }

    hres = CoInitializeSecurity(
        NULL,
        -1,                          // COM authentication
        NULL,                        // Authentication services
        NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication
        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
        NULL,                        // Authentication info
        EOAC_NONE,                   // Additional capabilities
        NULL                         // Reserved
    );


    if ((hres != RPC_E_TOO_LATE) && FAILED(hres))
    {
        qDebug() << "Failed to initialize security. Error code = 0x"
            << hex << hres << endl;
        CoUninitialize();
        return uuid;                    // Program has failed.
    }

    // Step 3: ---------------------------------------------------
    // Obtain the initial locator to WMI -------------------------

    IWbemLocator* pLoc = NULL;

    hres = CoCreateInstance(
        CLSID_WbemLocator,
        0,
        CLSCTX_INPROC_SERVER,
        IID_IWbemLocator, (LPVOID*)&pLoc);

    if (FAILED(hres))
    {
        qDebug() << "Failed to create IWbemLocator object."
            << " Err code = 0x"
            << hex << hres << endl;
        CoUninitialize();
        return uuid;                 // Program has failed.
    }

    // Step 4: -----------------------------------------------------
    // Connect to WMI through the IWbemLocator::ConnectServer method

    IWbemServices* pSvc = NULL;

    // Connect to the root\cimv2 namespace with
    // the current user and obtain pointer pSvc
    // to make IWbemServices calls.
    hres = pLoc->ConnectServer(
        _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
        NULL,                    // User name. NULL = current user
        NULL,                    // User password. NULL = current
        0,                       // Locale. NULL indicates current
        NULL,                    // Security flags.
        0,                       // Authority (e.g. Kerberos)
        0,                       // Context object
        &pSvc                    // pointer to IWbemServices proxy
    );

    if (FAILED(hres))
    {
        qDebug() << "Could not connect. Error code = 0x"
            << hex << hres << endl;
        pLoc->Release();
        CoUninitialize();
        return uuid;                // Program has failed.
    }

    //cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;

    // Step 5: --------------------------------------------------
    // Set security levels on the proxy -------------------------

    hres = CoSetProxyBlanket(
        pSvc,                        // Indicates the proxy to set
        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
        NULL,                        // Server principal name
        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx
        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
        NULL,                        // client identity
        EOAC_NONE                    // proxy capabilities
    );

    if (FAILED(hres))
    {
        cout << "Could not set proxy blanket. Error code = 0x"
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return uuid;               // Program has failed.
    }

    // Step 6: --------------------------------------------------
    // Use the IWbemServices pointer to make requests of WMI ----

    // For example, get the name of the operating system
    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        bstr_t("SELECT UUID FROM Win32_ComputerSystemProduct"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);
    if (FAILED(hres))
    {
        qDebug() << "Query for operating system name failed."
            << " Error code = 0x"
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return uuid;               // Program has failed.
    }

    // Step 7: -------------------------------------------------
    // Get the data from the query in step 6 -------------------

    IWbemClassObject* pclsObj;
    ULONG uReturn = 0;

    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
            &pclsObj, &uReturn);

        if (FAILED(hr) || 0 == uReturn)
        {
            break;
        }

        VARIANT vtProp;

        // Get the value of the Name property
        /*hr = pclsObj->Get(L"VolumeName", 0, &vtProp, 0, 0);
        wcout << " VolumeName : " << vtProp.bstrVal << endl;
        VariantClear(&vtProp);*/


        if (FAILED(pclsObj->Get(L"UUID", 0, &vtProp, 0, 0)))
        {
            qDebug() << "The specified property is not found." << endl;
        }
        else
        {
            qDebug() << vtProp.bstrVal << endl;
            QString q_str((QChar*)vtProp.bstrVal, wcslen(vtProp.bstrVal));
            uuid = q_str;
        }

        pclsObj->Release();
    }

    // Cleanup
    // ========

    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    // pclsObj->Release();
    CoUninitialize();

    qDebug() << "uuid: " << uuid << endl;
    return uuid;
}

速度在75ms

通过下面博客的代码可以实现获得CPUID:

【C/C++】获取计算机CPUID序列号_c++ 获取cpu序列号-CSDN博客

cpp 复制代码
std::string GetId()
{
    std::string strCPUId;
 
    unsigned long s1, s2;
    char buf[32] = { 0 };
 
    __asm
    {
        mov eax, 01h
        xor edx, edx
        cpuid
        mov s1, edx
        mov s2, eax
    }
 
    if (s1)
    {
        memset(buf, 0, 32);
        sprintf_s(buf, 32, "%08X", s1);
        strCPUId += buf;
    }
 
    if (s2)
    {
        memset(buf, 0, 32);
        sprintf_s(buf, 32, "%08X", s2);
        strCPUId += buf;
    }
 
    __asm
    {
        mov eax, 03h
        xor ecx, ecx
        xor edx, edx
        cpuid
        mov s1, edx
        mov s2, ecx
    }
 
    if (s1)
    {
        memset(buf, 0, 32);
        sprintf_s(buf, 32, "%08X", s1);
        strCPUId += buf;
    }
 
    if (s2)
    {
        memset(buf, 0, 32);
        sprintf_s(buf, 32, "%08X", s2);
        strCPUId += buf;
    }
 
    return strCPUId;
}

使用该函数将string转为QString

QString::fromStdString(GetCPUId());

时间消耗:

cpp 复制代码
#include <iostream>
#include <windows.h>

int main() {
    HKEY hKey;
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
        BYTE data[100];
        DWORD dataSize = sizeof(data);
        if (RegQueryValueEx(hKey, "MachineGuid", NULL, NULL, data, &dataSize) == ERROR_SUCCESS) {
            std::string machineGUID(reinterpret_cast<char*>(data));
            std::cout << "MachineGUID: " << machineGUID << std::endl;
        }
        RegCloseKey(hKey);
    }
    return 0;
}

Time elapsed: 24600 ns

Time elapsed: 0 ms

chatgpt真的很好用

获取MachineGUID

Windows API 获取MachineGUID_浇糖玛奇朵的博客-CSDN博客

cpp 复制代码
#include <Windows.h>
#include <string>
#include <iostream>
int main()
{
    std::string sub_key = "SOFTWARE\\Microsoft\\Cryptography";
    std::string name = "MachineGuid";
    HKEY hKey;
    DWORD dwType = REG_SZ;
    DWORD dwLen = MAX_PATH;
    if (RegOpenKeyA(HKEY_LOCAL_MACHINE, sub_key.c_str(), &hKey) == ERROR_SUCCESS) {
        std::cout << "ok\n";
    }
    unsigned char buf[100];
    PLONG data = 0;
    if (RegQueryValueExA(hKey, name.c_str(), 0, &dwType, (LPBYTE)buf, &dwLen) == ERROR_SUCCESS) {
        std::cout << "ok\n";
    }
    else std::cout << "GetLastError() = " << GetLastError() << std::endl;
    std::cout << buf << std::endl;
    return 0;
}

注意:

我的电脑是64位的,所以我的程序也得是64位才行,才能正确获得结果,否则,就访问失败。

这是一个非常重要的点,,,让我在坑里爬不出来。

【小沐学C++】C++ 访问注册表(64位系统)_c++ 32位及64位 注册表读写_爱看书的小沐的博客-CSDN博客

64位系统注册表分32位注册表项和64位注册表项两部分。

64位系统中,通过regedit中查看指定路径下的注册表项均为64位注册表项。

而32位注册表项被重定位到:HKEY_LOCAL_MACHINE\Software\WOW6432Node

写成下面这样就可以在32位应用程序中访问64位的注册表了。

cpp 复制代码
#include <Windows.h>
#include <string>
#include <iostream>
int main()
{
    std::string name = "MachineGuid";
    HKEY hKey;
    DWORD dwType = REG_SZ;
    DWORD dwLen = MAX_PATH;
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Cryptography",
        0, KEY_READ | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)
    {
        std::cout << "ok\n";
    }
    unsigned char buf[100];
    PLONG data = 0;
    if (RegQueryValueExA(hKey, name.c_str(), 0, &dwType, (LPBYTE)buf, &dwLen) == ERROR_SUCCESS) {
        std::cout << "ok\n";
    }
    else std::cout << "GetLastError() = " << GetLastError() << std::endl;
    std::cout << buf << std::endl;
    return 0;
}

封装一下:

cpp 复制代码
QString getMachineGUID()
{
    std::string name = "MachineGuid";
    HKEY hKey;
    DWORD dwType = REG_SZ;
    DWORD dwLen = MAX_PATH;
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Cryptography",
        0, KEY_READ | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)
    {
        std::cout << "ok\n";
    }
    unsigned char buf[100];
    PLONG data = 0;
    if (RegQueryValueExA(hKey, name.c_str(), 0, &dwType, (LPBYTE)buf, &dwLen) == ERROR_SUCCESS) {
        std::cout << "ok\n";
    }
    else std::cout << "GetLastError() = " << GetLastError() << std::endl;

    QString qstr = "";
    char* p = (char*)buf;
    qstr = qstr.append(p);
    qDebug() << qstr;
    return qstr;
}

花费时间:

cpp 复制代码
Time elapsed: 149100 ns
Time elapsed: 0 ms
相关推荐
zhuyasen1 小时前
踩坑实录:Go 1.25.x 编译的 exe 在 Windows 提示“此应用无法运行”
windows·golang
千歌叹尽执夏2 小时前
ubuntu24.04lts和Windows11家庭版远程桌面连接若干问题(解决)
windows·远程连接·xrdp·ubuntu24.04lts
sukalot10 小时前
Windows显示驱动开发-支持显示输出和 ACPI 事件
windows
爱隐身的官人10 小时前
Windows安全狗安装教程
windows·安全·安全设备
wulitoud12 小时前
[好用工具] 一款mac/windows电脑历史剪切板工具,类似著名的Paste
windows·macos·sublime text
APItesterCris13 小时前
构建弹性数据管道:利用淘宝商品 API 进行流式数据采集与处理
linux·数据库·windows
奋斗羊羊15 小时前
【C++】使用MSBuild命令行编译ACE、TAO、DDS
开发语言·c++·windows
郁大锤18 小时前
在 Windows 下安装与快速上手 Wireshark(抓包工具)
windows·测试工具·wireshark
路由侠内网穿透1 天前
本地部署开源持续集成和持续部署系统 Woodpecker CI 并实现外部访问
服务器·网络·windows·ci/cd·开源
CsharpDev-奶豆哥1 天前
ASP.NET中for和foreach使用指南
windows·microsoft·c#·asp.net·.net