C++调用Windows API获取已安装内存条运行频率等硬件信息的方法
Windows平台C++获取单条内存条硬件信息实现方案
你需要的单条内存运行频率、容量、厂商等细分硬件信息,无法通过sysinfoapi系列的常规内存API获取,有两种稳定的实现方式:
方案1:WMI查询Win32_PhysicalMemory类(推荐,开发成本低)
Windows的WMI组件内置了Win32_PhysicalMemory类,每一条实例对应一根已安装的物理内存条,常用属性如下:
Speed:内存当前运行频率,单位为MHzCapacity:单条内存总容量,单位为字节DeviceLocator:内存对应的插槽标识,例如DIMM A1Manufacturer:内存生产厂商字符串PartNumber:内存产品型号
对应的C++调用示例代码如下:
#include <windows.h> #include <wbemcli.h> #include <comdef.h> #pragma comment(lib, "wbemuuid.lib") int main() { HRESULT hres; // 初始化COM环境 hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) return 1; hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); if (FAILED(hres)) { CoUninitialize(); return 1; } IWbemLocator* pLoc = NULL; hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc); if (FAILED(hres)) { CoUninitialize(); return 1; } IWbemServices* pSvc = NULL; hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc); if (FAILED(hres)) { 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)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; } IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM Win32_PhysicalMemory"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; } 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(L"Speed", 0, &vtProp, 0, 0); wprintf(L"内存频率: %d MHz\n", vtProp.uintVal); VariantClear(&vtProp); // 获取内存容量 hr = pclsObj->Get(L"Capacity", 0, &vtProp, 0, 0); wprintf(L"内存容量: %llu GB\n", vtProp.ullVal / 1024 / 1024 / 1024); VariantClear(&vtProp); // 获取插槽位置 hr = pclsObj->Get(L"DeviceLocator", 0, &vtProp, 0, 0); wprintf(L"插槽位置: %s\n", vtProp.bstrVal); VariantClear(&vtProp); pclsObj->Release(); wprintf(L"------------------------\n"); } // 释放资源 pSvc->Release(); pLoc->Release(); pEnumerator->Release(); CoUninitialize(); return 0; }
方案2:读取SMBIOS表(底层方案,无依赖)
如果不想依赖WMI服务,可以调用GetSystemFirmwareTableAPI获取系统SMBIOS原始数据,自行解析Type 17类型的结构(对应物理内存设备信息),即可拿到所有单条内存的硬件参数,该方案更轻量,适合嵌入式类场景使用。
注意事项
- 两种方案都仅需要普通用户权限即可运行,无需管理员权限
- 部分虚拟机环境下可能无法获取到完整的内存硬件参数
内容的提问来源于stack exchange,提问作者Tyler Weiss
相关产品推荐
相关产品推荐

