wmi.h
#pragma once
#include <Windows.h>
#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>
#include <map>
#include <string>
#include <memory>
class wmiData {
public:
wmiData() { m_var.vt = VT_EMPTY; };
~wmiData() { VariantClear(&m_var); }
wmiData(const wmiData&& src) = delete;
wmiData(const wmiData& src)
{
m_var.vt = VT_EMPTY;
VariantCopy(&m_var, &src.m_var);
}
wmiData(const VARIANT& src)
{
m_var.vt = VT_EMPTY;
VariantCopy(&m_var, &src);
}
wmiData& operator=(const wmiData& src)
{
VariantClear(&m_var);
VariantCopy(&m_var, &src.m_var);
return *this;
}
wmiData& operator=(const VARIANT& src)
{
VariantClear(&m_var);
VariantCopy(&m_var, &src);
return *this;
}
const VARIANT& data() { return m_var; }
private:
VARIANT m_var;
};
class wmi
{
public:
static wmi& instance();
~wmi();
bool query(const wchar_t* query,std::map<std::wstring, wmiData>& vals);
private:
wmi();
IWbemLocator* m_pIwbe;
IWbemServices* m_pISvc;
};
wmi.cpp
#include "stdafx.h"
#include "wmi.h"
#pragma comment(lib, "wbemuuid.lib")
wmi& wmi::instance()
{
static wmi sInstance;
return sInstance;
}
wmi::wmi()
{
m_pIwbe = nullptr;
m_pISvc = nullptr;
// 初始化COM
HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
XLOGE("wmi initialize COM library failed. Error code = %d", (int)hres);
return;
}
// 初始化COM安全性
hres = CoInitializeSecurity(
nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE, nullptr);
if (FAILED(hres))
{
XLOGE("wmi initialize security failed. Error code = %d", (int)hres);
CoUninitialize();
return;
}
// 创建WMI实例
hres = CoCreateInstance(
CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, reinterpret_cast<LPVOID*>(&m_pIwbe));
if (FAILED(hres))
{
m_pIwbe = nullptr;
XLOGE("wmi create IWbemLocator object failed. Error code = %d", (int)hres);
CoUninitialize();
return;
}
// 连接到WMI
hres = m_pIwbe->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &m_pISvc);
if (FAILED(hres))
{
XLOGE("wmi connect to ROOT\\CIMV2 failed. Error code = %d", (int)hres);
m_pIwbe->Release();
m_pIwbe = nullptr;
m_pISvc = nullptr;
CoUninitialize();
return;
}
// 设置安全级别
hres = CoSetProxyBlanket(
m_pISvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);
if (FAILED(hres))
{
XLOGE("wmi set proxy blanket failed. Error code = %d", (int)hres);
m_pISvc->Release();
m_pIwbe->Release();
m_pISvc = nullptr;
m_pIwbe = nullptr;
CoUninitialize();
return;
}
}
wmi::~wmi()
{
if(m_pISvc)
m_pISvc->Release();
if (m_pIwbe)
m_pIwbe->Release();
m_pISvc = nullptr;
m_pIwbe = nullptr;
}
bool wmi::query(const wchar_t* query,std::map<std::wstring, wmiData>& vals)
{
vals.clear();
if (m_pISvc == nullptr) return false;
// 执行WMI查询
IEnumWbemClassObject* pEnumerator = nullptr;
HRESULT hres = m_pISvc->ExecQuery(
_bstr_t(L"WQL"), _bstr_t(query), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, &pEnumerator);
if (FAILED(hres))
{
XLOGE("wmi Query for data failed. Error code = %d", (int)hres);
return false;
}
// 枚举查询结果
IWbemClassObject* pclsObj = nullptr;
ULONG uReturn = 0;
while (pEnumerator)
{
hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (uReturn == 0)
break;
SAFEARRAY *pary = NULL;
hres = pclsObj->GetNames(NULL, WBEM_FLAG_ALWAYS, NULL, &pary);
if (SUCCEEDED(hres))
{
long lBound, uBound;
SafeArrayGetLBound(pary, 1, &lBound); // 获取下界
SafeArrayGetUBound(pary, 1, &uBound); // 获取上界
BSTR* pVarDataAry = NULL;
SafeArrayAccessData(pary, reinterpret_cast<void**>(&pVarDataAry));
for (long i = lBound; i <= uBound; ++i)
{
const BSTR& pItem = pVarDataAry[i];
// 获取属性值
VARIANT vtProp;
hres = pclsObj->Get((LPCWSTR)pItem, 0, &vtProp, 0, 0);
if (SUCCEEDED(hres))
{
vals[std::wstring((LPCWSTR)pItem)] = vtProp;
VariantClear(&vtProp);
}
}
if(pVarDataAry)
SafeArrayUnaccessData(pary);
SafeArrayDestroy(pary);
}
pclsObj->Release();
}
// 释放资源
pEnumerator->Release();
return true;
}
main.cpp
auto query = []() {
//while (true)
{
std::map<std::wstring, wmiData> vals;
wmi::instance().query(L"SELECT * FROM Win32_VideoController", vals);
Sleep(100);
}
};
std::thread t(query);
std::thread t0(query);
std::thread t1(query);

2万+

被折叠的 条评论
为什么被折叠?



