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
相关推荐
emplace_back1 小时前
C# 集合表达式和展开运算符 (..) 详解
开发语言·windows·c#
一禅(OneZen)5 小时前
「Windows/Mac OS」AIGC图片生成视频 ,webui + stable-diffusion环境部署教程
windows·stable diffusion
AirDroid_cn6 小时前
OPPO手机怎样被其他手机远程控制?两台OPPO手机如何相互远程控制?
android·windows·ios·智能手机·iphone·远程工作·远程控制
小龙在山东8 小时前
Python 包管理工具 uv
windows·python·uv
昏睡红猹8 小时前
我在厂里搞wine的日子
windows·wine
love530love11 小时前
Docker 稳定运行与存储优化全攻略(含可视化指南)
运维·人工智能·windows·docker·容器
1024小神16 小时前
tauri项目在windows上的c盘没有权限写入文件
c语言·开发语言·windows
程序视点1 天前
Window 10文件拷贝总是卡很久?快来试试这款小工具,榨干硬盘速度!
windows
wuk9981 天前
基于MATLAB编制的锂离子电池伪二维模型
linux·windows·github
lzb_kkk1 天前
【C++】C++四种类型转换操作符详解
开发语言·c++·windows·1024程序员节