Win32 Provider不仅仅提供类和实例的信息,而且有些Provider会提供了一些方法,供用户调用。调用方法的流程如下:
1)取得Provider实例对象
调用IWbemServices::GetObject方法可以取得我们想要调用的Provider类型实例,他以一个IWbemClassObject类型指针返回。
BSTR MethodName
=
SysAllocString(L
"
Create
"
);
BSTR ClassName
=
SysAllocString(L
"
Win32_Process
"
);
IWbemClassObject
*
pClass
=
NULL;
hres
=
pSvc
->
GetObject(ClassName,
0
, NULL,
&
pClass, NULL);
2)取得Provider提供方法参数
调用IWbemClassObject::GetMethod方法可以取得我们想要调用方法的参数,他以一个IWbemClassObject类型指针返回。
IWbemClassObject
*
pInParamsDefinition
=
NULL;
hres
=
pClass
->
GetMethod(MethodName,
0
,
&
pInParamsDefinition, NULL);
3)生成Provider提供方法的参数的对象
调用IWbemClassObject::SpawnInstance方法生成调用方法的参数实例。需要将第二步得到的参数类型指针调用这个SpawnInstance方法,并且传递给该方法一个IWbemClassObject指针作为生成的参数对象的指针。
IWbemClassObject
*
pClassInstance
=
NULL;
hres
=
pInParamsDefinition
->
SpawnInstance(
0
,
&
pClassInstance);
4)设置参数对象的属性
调用IWbemClassObject::Put方法就可以设置参数对象的类型。
VARIANT varCommand;
varCommand.vt
=
VT_BSTR;
varCommand.bstrVal
=
L
"
notepad.exe
"
;
hres
=
pClassInstance
->
Put(L
"
CommandLine
"
,
0
,
&
varCommand,
0
);
wprintf(L
"
The command is: %s
"
, V_BSTR(
&
varCommand));
5)调用方法
与查询信息相同,调用方法也可以分为同步方式和异步方式,同步方式等待执行进程结束,才继续往下执行;异步方式则利用实现IWbemObjectSink接口的类型,创建一个新的线程后继续运行当前线程,而由新创建的线程完成调用方法,然后回调IWbemObjectSink:: Indicate函数,处理函数返回值。
以下是以同步方式调用IWbemServices::ExecMethod方法即调用Provider提供的方法,将之前生成的关于参数的实例传给该方法即可。
IWbemClassObject
*
pOutParams
=
NULL;
hres
=
pSvc
->
ExecMethod(ClassName, MethodName,
0
,
NULL, pClassInstance,
&
pOutParams, NULL);
以下是以异步方式调用同样的Provider的函数,不同于同步方式,异步方式调用IWbemServices::ExecMethodAsync方法,第三个参数IFlag可以设置为WBEM_FLAG_SEND_STATUS以接受调用时中间状态信息,没有输出参数(本例中是pOutParams),最后一个参数是实现IWbemObjectSink接口的类型。
QuerySink
*
pSink
=
new
QuerySink();
hres
=
pSvc
->
ExecMethodAsync(ClassName, MethodName, WBEM_FLAG_SEND_STATUS,
NULL, pClassInstance, pSink);
但是调用方法比查询信息多出一种半同步方式,由于同步方法使得调用者线程等待方法执行完,而异步方法则需要编程人员继承IWbemObjectSink接口并进行多线程编程,所以半同步方式则是以一种折中的方法进行IWbemServices实例中方法的调用,创建一个线程去查询,然后写入一个IWbemCallResult接口的实例中,由主线程去查询。
IWbemCallResult
*
pCallRes
=
0
;
IWbemClassObject
*
pObj
=
0
;
hres
=
pSvc
->
ExecMethod(ClassName, MethodName, WBEM_FLAG_RETURN_IMMEDIATELY,
NULL, pClassInstance,NULL,
&
pCallRes);
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
while
(
true
)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
LONG lStatus = 0;
HRESULT hRes = pCallRes->GetCallStatus(5000, &lStatus);
if ((hRes == WBEM_S_NO_ERROR))
break;
if ((hRes == WBEM_S_TIMEDOUT))
continue;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
hres
=
pCallRes
->
GetResultObject(
5000
,
&
pObj);
if
(hres)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
pCallRes->Release();
return 1;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
VARIANT varReturnValue;
hres
=
pObj
->
Get(_bstr_t(L
"
ReturnValue
"
),
0
,
&
varReturnValue, NULL,
0
);
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
cout
<<
varReturnValue.lVal
<<
endl;
pCallRes
->
Release();
pObj
->
Release();
以上就是通过WMI调用方法的基本形式,在XP下,调用方法的功能比较少,但是在Vista下,Windows在root/wmi命名空间中提供了一些Provider和方法,代替了一些本来由驱动做的事情。
但是比较遗憾的是,MSDN上一些文档与MS提供的WMI Tool所实际体现的数据不一致,像WmiSetBrightnessMethods类的SetBrightness方法的两个参数就有这样的情况,uint8和uint64好像也是为dotNet平台所准备的一样,在Put进去这两个参数后, hres 返回S_OK,但是在execMethod时,就会出现类型不匹配的错误,让人比较挠头~希望如果有朋友路过且恰巧知道如何用C++COM调用这个方法可以给我留言,或者加我QQ,十分感谢!
1)取得Provider实例对象
调用IWbemServices::GetObject方法可以取得我们想要调用的Provider类型实例,他以一个IWbemClassObject类型指针返回。
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
调用IWbemClassObject::GetMethod方法可以取得我们想要调用方法的参数,他以一个IWbemClassObject类型指针返回。
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
调用IWbemClassObject::SpawnInstance方法生成调用方法的参数实例。需要将第二步得到的参数类型指针调用这个SpawnInstance方法,并且传递给该方法一个IWbemClassObject指针作为生成的参数对象的指针。
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
调用IWbemClassObject::Put方法就可以设置参数对象的类型。
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
与查询信息相同,调用方法也可以分为同步方式和异步方式,同步方式等待执行进程结束,才继续往下执行;异步方式则利用实现IWbemObjectSink接口的类型,创建一个新的线程后继续运行当前线程,而由新创建的线程完成调用方法,然后回调IWbemObjectSink:: Indicate函数,处理函数返回值。
以下是以同步方式调用IWbemServices::ExecMethod方法即调用Provider提供的方法,将之前生成的关于参数的实例传给该方法即可。
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
以上就是通过WMI调用方法的基本形式,在XP下,调用方法的功能比较少,但是在Vista下,Windows在root/wmi命名空间中提供了一些Provider和方法,代替了一些本来由驱动做的事情。
但是比较遗憾的是,MSDN上一些文档与MS提供的WMI Tool所实际体现的数据不一致,像WmiSetBrightnessMethods类的SetBrightness方法的两个参数就有这样的情况,uint8和uint64好像也是为dotNet平台所准备的一样,在Put进去这两个参数后, hres 返回S_OK,但是在execMethod时,就会出现类型不匹配的错误,让人比较挠头~希望如果有朋友路过且恰巧知道如何用C++COM调用这个方法可以给我留言,或者加我QQ,十分感谢!