【windows】【wmi】ExecQuery的简单封装

概述:wmi的简单封装,主要实现查询功能,即 ExecQuery 接口

实现

头文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*************************************************************************************************
*
* File Name : WMIInof.h
*
* Created : 2023/10/19
*
* Author : holdyounger
*
* Model :
*
* Description : simple wmi execquery
*
**************************************************************************************************/
#ifndef _WMIINFO_H_
#define _WMIINFO_H_

#include <WbemIdl.h>
#pragma comment(lib,"WbemUuid.lib")

class CWmiInfo
{
public:
CWmiInfo();
~CWmiInfo();

public:
HRESULT InitWmi(); //初始化WMI
HRESULT ReleaseWmi(); //释放

/*获取一个类成员
*@param [in ] ClassName Example: "Win32_Processor"
*@param [in ] ClassMember Example: "SerialNumber"
*@param [out] chRetValue
*@param return TRUE success; false fail

Example:
CString strRetValue;
GetSingleItemInfo(_T("Win32_Processor"),_T("Caption"),strRetValue);
*/
BOOL GetSingleItemInfo(CString ClassName,CString ClassMember,CString &chRetValue);

/*获取一个类的多个成员
*@param [in ] ClassName Example: "Win32_Processor"
*@param [in ] ClassMember Example: "SerialNumber"
*@param [in ] n 成员个数
*@param [out] chRetValue
*@param return TRUE success; false fail

Example:
CString strRetValue;CString [] strClassMem = {_T("Caption"),_T("CurrentClockSpeed"),_T("DeviceID"),_T("Manufacturer"),_T("Manufacturer")};
GetGroupItemInfo(_T("Win32_Processor"),strClassMem,5,strRetValue);
*/
BOOL GetGroupItemInfo(CString ClassName,CString ClassMember[],int n,CString &chRetValue);

private:
void VariantToString(const LPVARIANT,CString &) const;//将Variant类型的变量转换为CString

private:
IEnumWbemClassObject* m_pEnumClsObj;
IWbemClassObject* m_pWbemClsObj;
IWbemServices* m_pWbemSvc;
IWbemLocator* m_pWbemLoc;
};
#endif

源文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
#include "stdafx.h"
#include "WmiInfo.h"

CWmiInfo::CWmiInfo(void)
{
m_pWbemSvc=NULL;
m_pWbemLoc=NULL;
m_pEnumClsObj = NULL;
}

CWmiInfo::~CWmiInfo(void)
{
m_pWbemSvc=NULL;
m_pWbemLoc=NULL;
m_pEnumClsObj = NULL;
}

HRESULT CWmiInfo::InitWmi()
{
HRESULT hr;

//一、初始化COM组件
//初始化COM
hr=::CoInitializeEx(0,COINIT_MULTITHREADED);
if (SUCCEEDED(hr) || RPC_E_CHANGED_MODE == hr)
{
//设置进程的安全级别,(调用COM组件时在初始化COM之后要调用CoInitializeSecurity设置进程安全级别,否则会被系统识别为病毒)
hr=CoInitializeSecurity(NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL);
//VERIFY(SUCCEEDED(hr));

//二、创建一个WMI命名空间连接
//创建一个CLSID_WbemLocator对象
hr=CoCreateInstance(CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(LPVOID*)&m_pWbemLoc);
// VERIFY(SUCCEEDED(hr));

//使用m_pWbemLoc连接到"root\cimv2"并设置m_pWbemSvc的指针
hr=m_pWbemLoc->ConnectServer(CComBSTR(L"ROOT\\CIMV2"),
NULL,
NULL,
0,
NULL,
0,
0,
&m_pWbemSvc);
// VERIFY(SUCCEEDED(hr));

//三、设置WMI连接的安全性
hr=CoSetProxyBlanket(m_pWbemSvc,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE);
// VERIFY(SUCCEEDED(hr));

}
return(hr);
}

HRESULT CWmiInfo::ReleaseWmi()
{
HRESULT hr;

if (NULL != m_pWbemSvc)
{
hr=m_pWbemSvc->Release();
}
if (NULL != m_pWbemLoc)
{
hr=m_pWbemLoc->Release();
}
if (NULL != m_pEnumClsObj)
{
hr=m_pEnumClsObj->Release();
}

::CoUninitialize();

return(hr);
}

BOOL CWmiInfo::GetSingleItemInfo(CString ClassName,CString ClassMember,CString &chRetValue)
{
USES_CONVERSION;

CComBSTR query("SELECT * FROM ");
VARIANT vtProp;
ULONG uReturn;
HRESULT hr;
BOOL bRet = FALSE;

if (NULL != m_pWbemSvc)
{
//查询类ClassName中的所有字段,保存到m_pEnumClsObj中
query+=CComBSTR(ClassName);
hr=m_pWbemSvc->ExecQuery(CComBSTR("WQL"),query,WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
0,&m_pEnumClsObj);
if (SUCCEEDED(hr))
{
//初始化vtProp值
VariantInit(&vtProp);
uReturn=0;

//返回从当前位置起的第一个对象到m_pWbemClsObj中
hr=m_pEnumClsObj->Next(WBEM_INFINITE,1,&m_pWbemClsObj,&uReturn);
if(SUCCEEDED(hr)&&uReturn>0)
{
//从m_pWbemClsObj中找出ClassMember标识的成员属性值,并保存到vtProp变量中
hr=m_pWbemClsObj->Get(CComBSTR(ClassMember),0,&vtProp,0,0);
if (SUCCEEDED(hr))
{
VariantToString(&vtProp,chRetValue);
VariantClear(&vtProp);//清空vtProp
bRet = TRUE;
}
}
}
}
if(NULL != m_pEnumClsObj)
{
hr=m_pEnumClsObj->Release();
m_pEnumClsObj = NULL;
}
if(NULL != m_pWbemClsObj)
{
hr=m_pWbemClsObj->Release();
m_pWbemClsObj = NULL;
}
return bRet;
}

BOOL CWmiInfo::GetGroupItemInfo(CString ClassName,CString ClassMember[],int n,CString &chRetValue)
{
USES_CONVERSION;

CComBSTR query("SELECT * FROM ");
CString result,info;
VARIANT vtProp;
ULONG uReturn;
HRESULT hr;
int i;
BOOL bRet = FALSE;
if (NULL != m_pWbemSvc)
{
query+=CComBSTR(ClassName);
hr=m_pWbemSvc->ExecQuery(CComBSTR("WQL"),query,WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,0,&m_pEnumClsObj);
if (SUCCEEDED(hr))
{
VariantInit(&vtProp); //初始化vtProp变量
if(m_pEnumClsObj)
{
Sleep(10);
uReturn=0;
hr=m_pEnumClsObj->Next(WBEM_INFINITE,1,&m_pWbemClsObj,&uReturn);
if (SUCCEEDED(hr) &&uReturn>0)
{
for(i=0;i<n;++i)
{
hr=m_pWbemClsObj->Get(CComBSTR(ClassMember[i]),0,&vtProp,0,0);
if (SUCCEEDED(hr))
{
VariantToString(&vtProp,info);
chRetValue+=info+_T("\t");
VariantClear(&vtProp);
bRet = TRUE;
}
}
chRetValue+=_T("\r\n");
}
}
}
}

if(NULL != m_pEnumClsObj)
{
hr=m_pEnumClsObj->Release();
m_pEnumClsObj=NULL;
}
if(NULL != m_pWbemClsObj)
{
hr=m_pWbemClsObj->Release();
m_pWbemClsObj=NULL;
}
return bRet;
}

void CWmiInfo::VariantToString(const LPVARIANT pVar,CString &chRetValue) const
{
USES_CONVERSION;

CComBSTR HUGEP* pBstr;
BYTE HUGEP* pBuf;
LONG low,high,i;
HRESULT hr;

switch(pVar->vt)
{
case VT_BSTR:
{
chRetValue=W2T(pVar->bstrVal);
}
break;
case VT_BOOL:
{
if(VARIANT_TRUE==pVar->boolVal)
chRetValue="是";
else
chRetValue="否";
}
break;
case VT_I4:
{
chRetValue.Format(_T("%d"),pVar->lVal);
}
break;
case VT_UI1:
{
chRetValue.Format(_T("%d"),pVar->bVal);
}
break;
case VT_UI4:
{
chRetValue.Format(_T("%d"),pVar->ulVal);
}
break;

case VT_BSTR|VT_ARRAY:
{
hr=SafeArrayAccessData(pVar->parray,(void HUGEP**)&pBstr);
hr=SafeArrayUnaccessData(pVar->parray);
chRetValue=W2T(pBstr->m_str);
}
break;

case VT_I4|VT_ARRAY:
{
SafeArrayGetLBound(pVar->parray,1,&low);
SafeArrayGetUBound(pVar->parray,1,&high);

hr=SafeArrayAccessData(pVar->parray,(void HUGEP**)&pBuf);
hr=SafeArrayUnaccessData(pVar->parray);
CString strTmp;
high=min(high,MAX_PATH*2-1);
for(i=low;i<=high;++i)
{
strTmp.Format(_T("%02X"),pBuf[i]);
chRetValue+=strTmp;
}
}
break;
default:
break;
}
}

使用

1


【windows】【wmi】ExecQuery的简单封装
https://hodlyounger.github.io/A_OS/Windows/WMI/WMI execquery 接口封装/
作者
mingming
发布于
2023年10月27日
许可协议