9月20日学习记录

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

使用chatgpt生成的:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
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博客

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()); 

时间消耗: 

#include 
#include 

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(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博客

#include 
#include 
#include 
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位的注册表了。

#include 
#include 
#include 
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;
}

封装一下:

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;
}

花费时间: 

Time elapsed: 149100 ns
Time elapsed: 0 ms

你可能感兴趣的:(windows)