WMI查询

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

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值