【WMI-4】WMI For C++/COM 调用方法

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

    
while  ( true )
    
{
        LONG lStatus 
= 0;
        HRESULT hRes 
= pCallRes->GetCallStatus(5000&lStatus);
        
if ((hRes == WBEM_S_NO_ERROR))
            
break;
        
if ((hRes == WBEM_S_TIMEDOUT))
            
continue;
    }


    hres 
=  pCallRes -> GetResultObject( 5000 & pObj);
    
if  (hres)
    
{
        pCallRes
->Release();
        
return 1;
    }


    VARIANT varReturnValue;
    hres 
=  pObj -> Get(_bstr_t(L " ReturnValue " ),  0
        
& varReturnValue, NULL,  0 );

    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,十分感谢!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值