C++获取硬件参数的示例详解

 更新时间:2024年11月20日 09:21:23   作者:阿征学IT  
这篇文章主要为大家详细介绍了如何使用C++获取硬件参数,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

分别显示

cpu参数

显卡参数

硬盘参数

内存信息(随机存储器容量)

代码

#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>
 
#pragma comment(lib, "wbemuuid.lib")
 
void QueryWMI(IWbemServices* pSvc, const wchar_t* query, const wchar_t* propertyName) {
    IEnumWbemClassObject* pEnumerator = NULL;
    HRESULT hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        bstr_t(query),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);
 
    if (FAILED(hres)) {
        std::cerr << "Query failed. Error code = 0x" << std::hex << hres << std::endl;
        return;
    }
 
    IWbemClassObject* pclsObj = NULL;
    ULONG uReturn = 0;
 
    while (pEnumerator) {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
 
        if (0 == uReturn) {
            break;
        }
 
        VARIANT vtProp;
        hr = pclsObj->Get(propertyName, 0, &vtProp, 0, 0);
        if (SUCCEEDED(hr) && vtProp.vt != VT_NULL) {
            std::wcout << propertyName << L" : " << vtProp.bstrVal << std::endl;
        }
        else {
            std::wcout << propertyName << L" : Not available" << std::endl;
        }
        VariantClear(&vtProp);
 
        pclsObj->Release();
    }
 
    pEnumerator->Release();
}
 
int main() {
    HRESULT hres;
 
    // Initialize COM.
    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres)) {
        std::cerr << "Failed to initialize COM library. Error code = 0x" << std::hex << hres << std::endl;
        return 1;
    }
 
    // Initialize security.
    hres = CoInitializeSecurity(
        NULL,
        -1,
        NULL,
        NULL,
        RPC_C_AUTHN_LEVEL_DEFAULT,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL,
        EOAC_NONE,
        NULL);
 
    if (FAILED(hres)) {
        std::cerr << "Failed to initialize security. Error code = 0x" << std::hex << hres << std::endl;
        CoUninitialize();
        return 1;
    }
 
    IWbemLocator* pLoc = NULL;
    hres = CoCreateInstance(
        CLSID_WbemLocator,
        0,
        CLSCTX_INPROC_SERVER,
        IID_IWbemLocator, (LPVOID*)&pLoc);
 
    if (FAILED(hres)) {
        std::cerr << "Failed to create IWbemLocator object. Error code = 0x" << std::hex << hres << std::endl;
        CoUninitialize();
        return 1;
    }
 
    IWbemServices* pSvc = NULL;
    hres = pLoc->ConnectServer(
        _bstr_t(L"ROOT\\CIMV2"),
        NULL,
        NULL,
        0,
        NULL,
        0,
        0,
        &pSvc);
 
    if (FAILED(hres)) {
        std::cerr << "Could not connect. Error code = 0x" << std::hex << hres << std::endl;
        pLoc->Release();
        CoUninitialize();
        return 1;
    }
 
    hres = CoSetProxyBlanket(
        pSvc,
        RPC_C_AUTHN_WINNT,
        RPC_C_AUTHZ_NONE,
        NULL,
        RPC_C_AUTHN_LEVEL_CALL,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL,
        EOAC_NONE);
 
    if (FAILED(hres)) {
        std::cerr << "Could not set proxy blanket. Error code = 0x" << std::hex << hres << std::endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;
    }
 
    // Query hardware information
    std::wcout << L"CPU Information:" << std::endl;
    QueryWMI(pSvc, L"SELECT Name, NumberOfCores, MaxClockSpeed FROM Win32_Processor", L"Name");
 
    std::wcout << L"\nGPU Information:" << std::endl;
    QueryWMI(pSvc, L"SELECT Name, AdapterRAM, DriverVersion FROM Win32_VideoController", L"Name");
 
    std::wcout << L"\nDisk Information:" << std::endl;
    QueryWMI(pSvc, L"SELECT Model, Size, InterfaceType FROM Win32_DiskDrive", L"Model");
 
    std::wcout << L"\nMemory Information:" << std::endl;
    QueryWMI(pSvc, L"SELECT Capacity, Speed, Manufacturer FROM Win32_PhysicalMemory", L"Capacity");
 
    // Cleanup
    pSvc->Release();
    pLoc->Release();
    CoUninitialize();
 
    return 0;
}

头文件部分

iostream:用于输入输出操作(std::wcout)。

comdef.h 和 Wbemidl.h:支持 COM(Component Object Model)和 WMI(Windows Management Instrumentation)接口。

#pragma comment(lib, "wbemuuid.lib"):将 wbemuuid.lib 动态链接库包含到项目中,这是 WMI 所需的库。

函数部分

QueryWMI 函数

这是一个通用的函数,用于执行 WMI 查询并获取指定属性的信息。

void QueryWMI(IWbemServices* pSvc, const wchar_t* query, const wchar_t* propertyName) {
    IEnumWbemClassObject* pEnumerator = NULL;
    HRESULT hres = pSvc->ExecQuery(
        bstr_t("WQL"),  // 使用 WMI Query Language (WQL)
        bstr_t(query),  // 执行查询字符串
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);

输入参数

pSvc:WMI 服务接口,用于执行查询。

query:WMI 查询字符串,例如 SELECT Name FROM Win32_Processor。

propertyName:要获取的属性名,例如 Name。

WMI 查询:

使用 IWbemServices::ExecQuery 执行 WQL 查询。

WBEM_FLAG_FORWARD_ONLY 和 WBEM_FLAG_RETURN_IMMEDIATELY 是优化标志,用于快速返回结果。

if (FAILED(hres)) {
    std::cerr << "Query failed. Error code = 0x" << std::hex << hres << std::endl;
    return;
}

检查查询是否成功,如果失败,打印错误代码。

遍历查询结果

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

使用 IEnumWbemClassObject::Next 获取查询结果,逐条处理

WBEM_INFINITE 指定无限等待时间

获取指定属性值

VARIANT vtProp;
hr = pclsObj->Get(propertyName, 0, &vtProp, 0, 0);
if (SUCCEEDED(hr) && vtProp.vt != VT_NULL) {
    std::wcout << propertyName << L" : " << vtProp.bstrVal << std::endl;
} else {
    std::wcout << propertyName << L" : Not available" << std::endl;
}
VariantClear(&vtProp);

调用 IWbemClassObject::Get 获取指定属性值

成功:打印属性值

失败或属性值为空:打印 "Not available"。

用 VariantClear 释放变量的内存。

Main 函数

一,初始化 COM

hres = CoInitializeEx(0, COINIT_MULTITHREADED);

二,设置安全性

hres = CoInitializeSecurity(
    NULL,
    -1,
    NULL,
    NULL,
    RPC_C_AUTHN_LEVEL_DEFAULT,
    RPC_C_IMP_LEVEL_IMPERSONATE,
    NULL,
    EOAC_NONE,
    NULL);

配置 COM 安全性,确保当前进程有足够权限访问 WMI。

RPC_C_IMP_LEVEL_IMPERSONATE:允许服务器模拟客户端

三,创建 WMI 接口对象

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

使用 CoCreateInstance 创建 IWbemLocator 对象。该对象用于连接到 WMI 服务。

四,连接到 WMI 服务

hres = pLoc->ConnectServer(
    _bstr_t(L"ROOT\\CIMV2"),
    NULL,
    NULL,
    0,
    NULL,
    0,
    0,
    &pSvc);

连接到 ROOT\CIMV2 命名空间,这是获取硬件信息的常用命名空间。

pSvc 是连接后的服务接口。

五,设置代理

hres = CoSetProxyBlanket(
    pSvc,
    RPC_C_AUTHN_WINNT,
    RPC_C_AUTHZ_NONE,
    NULL,
    RPC_C_AUTHN_LEVEL_CALL,
    RPC_C_IMP_LEVEL_IMPERSONATE,
    NULL,
    EOAC_NONE);

配置代理,为调用的 WMI 服务接口提供身份验证

六,查询硬件信息

std::wcout << L"CPU Information:" << std::endl;
QueryWMI(pSvc, L"SELECT Name, NumberOfCores, MaxClockSpeed FROM Win32_Processor", L"Name");
 
std::wcout << L"\nGPU Information:" << std::endl;
QueryWMI(pSvc, L"SELECT Name, AdapterRAM, DriverVersion FROM Win32_VideoController", L"Name");
 
std::wcout << L"\nDisk Information:" << std::endl;
QueryWMI(pSvc, L"SELECT Model, Size, InterfaceType FROM Win32_DiskDrive", L"Model");
 
std::wcout << L"\nMemory Information:" << std::endl;
QueryWMI(pSvc, L"SELECT Capacity, Speed, Manufacturer FROM Win32_PhysicalMemory", L"Capacity");

调用 QueryWMI 函数分别获取 CPU、GPU、硬盘和内存的硬件信息。 

七,清理

pSvc->Release();
pLoc->Release();
CoUninitialize();

释放 IWbemServices 和 IWbemLocator 接口。调用 CoUninitialize 关闭 COM。

运行结果如下

以上就是C++获取硬件参数的示例详解的详细内容,更多关于C++获取硬件参数的资料请关注脚本之家其它相关文章!

相关文章

  • C++实现LeetCode(103.二叉树的之字形层序遍历)

    C++实现LeetCode(103.二叉树的之字形层序遍历)

    这篇文章主要介绍了C++实现LeetCode(103.二叉树的之字形层序遍历),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C语言实现散列表(哈希Hash表)实例详解

    C语言实现散列表(哈希Hash表)实例详解

    这篇文章主要介绍了C语言实现散列表(哈希Hash表)实例详解的相关资料,需要的朋友可以参考下
    2017-06-06
  • 浅析直接插入排序与折半插入排序

    浅析直接插入排序与折半插入排序

    这篇文章主要介绍了直接插入排序与折半插入排序,有需要的朋友可以参考一下
    2013-12-12
  • C++中地图按键排序实现示例

    C++中地图按键排序实现示例

    这篇文章主要为大家介绍了C++中地图按键排序实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • c语言动态内存分配知识点及实例

    c语言动态内存分配知识点及实例

    在本篇文章里小编给大家整理的是关于c语言动态内存分配知识点及实例,需要的朋友们可以学习下。
    2020-03-03
  • 通过c语言调用系统curl动态库的示例详解

    通过c语言调用系统curl动态库的示例详解

    这篇文章中我们将通过一个简单的示例来讲解如何在Ubuntu系统中通过C语言调用动态库(共享库)的方法,我们将使用libcurl库,这是一个基于客户端的URL传输库,广泛用于各种程序和应用中以访问网页和服务器数据,需要的朋友可以参考下
    2024-03-03
  • C++中引用&与取地址&的区别分析

    C++中引用&与取地址&的区别分析

    这篇文章主要介绍了C++中引用&与取地址&的区别,有助于C++初学者更好的掌握指针的概念及用法,需要的朋友可以参考下
    2014-09-09
  • c++中new和delete操作符用法

    c++中new和delete操作符用法

    c++中new和delete运算符是用于动态分配和撤销内存的运算符,下面是示例,大家参考使用吧
    2014-04-04
  • C语言位图算法详解

    C语言位图算法详解

    这篇文章主要介绍了C语言实现的位图算法,主要包括了位图算法的定义与应用,对于C程序算法设计的学习有一定的借鉴价值,需要的朋友可以参考下
    2014-09-09
  • C++文件读取的4种情况汇总

    C++文件读取的4种情况汇总

    前几天要用到C++读取文本文件,就学习了一下几种不同的读取方法,下面这篇文章主要给大家介绍了关于C++文件读取的4种情况,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-01-01

最新评论