none
关于win32使用com编程的问题 RRS feed

  • 问题

  • 如以下代码,查询不同的字段,经常会在 HRESULT hr = pEnumerator->Next( WBEM_INFINITE, 1,  &pclsObj, &uReturn ); 这句报出异常,读取0x....错误,该如何处理呢?

    #include "stdafx.h"
    #define _WIN32_DCOM
    #include <atlcomcli.h>
    //#include <iostream>
    using namespace std;
    #include <comdef.h>
    #include <Wbemidl.h>
    #include "wing_string.h"

    # pragma comment(lib, "wbemuuid.lib")

    class WingWmic{
    private:
    IWbemServices *pSvc; 
    int has_error; 
    IEnumWbemClassObject* pEnumerator; 
    IWbemLocator *pLoc; 
    char *query_table;
    public:
    WingWmic();
    ~WingWmic();
    void query( const char *sql );
    BOOL next();
    char* get( const char *key);
    };

    WingWmic::WingWmic(){

    this->pSvc = NULL;
    this->pEnumerator = NULL;
    this->has_error = 0;
    this->pLoc = NULL;
    this->query_table   = NULL;

    HRESULT hres;
        hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 
        if (FAILED(hres))
        {
    this->has_error = 1;
            return;             
        }

        hres =  CoInitializeSecurity( NULL, -1,  NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );

    if (FAILED(hres))
        {
    this->has_error = 1;
            return ;
        }


        hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,  IID_IWbemLocator, (LPVOID *) &pLoc );

        if (FAILED(hres))
        {
    this->has_error = 1;
            return ;            
        }

        hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), NULL, NULL,  0,  NULL,  0,  0,   &this->pSvc  );

        if (FAILED(hres))
        {   
    this->has_error = 1;
            return ;             
        }

        hres = CoSetProxyBlanket( pSvc,  RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,  NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE,  NULL,  EOAC_NONE );

        if (FAILED(hres))
        {    
    this->has_error = 1;
            return;        
        }

    }

    WingWmic::~WingWmic(){
    if( pSvc != NULL ) 
    pSvc->Release();
        if( pLoc != NULL ) 
    pLoc->Release();
        if( pEnumerator != NULL )
    pEnumerator->Release();
    if( this->query_table != NULL ) 
    delete[] this->query_table;
        CoUninitialize();
    }


    void WingWmic::query( const char* _sql ){

    if( this->has_error ) return;
    char *sql = _strdup( _sql );

    int i = 0;
    while( sql[i] != '\0' ){
    sql[i] = tolower(sql[i]);
    i++;
    }

    char *from = strstr( sql , "from" )+4;
    while( 1 ) {
    char c = *from;
    if( !isspace(c) ) break;
    from++;
    }

    this->query_table = new char[32];
    memset( this->query_table , 0 , 32);
    int index = 0;
    while(1) {
    char c = *from;
    if( isspace(c) || c == '\0' ) break;
    this->query_table[index] = c;
    index++;
    from++;
    }

    //printf("table=%s\r\n",this->query_table);

    HRESULT hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t(sql),WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL,&this->pEnumerator);

    if (FAILED(hres))
    {
    this->has_error = 1;
    }

    delete[] sql;
    }

    BOOL WingWmic::next(){
    return !!pEnumerator;
    }

    char* WingWmic::get( const char *key){

    SetLastError(0);

    if( this->has_error ) 
    {
    //printf("has error %ld\r\n",GetLastError());
    pEnumerator->Release();
    pEnumerator = NULL;
    return NULL;
    }

    IWbemClassObject *pclsObj = NULL;
        ULONG uReturn = 0;

    HRESULT hr = pEnumerator->Next( WBEM_INFINITE, 1,  &pclsObj, &uReturn );

    if( 0 == uReturn )
    {
    //printf("\r\nfail %ld\r\n",GetLastError());
    if( pclsObj != NULL ) {
    pclsObj->Release();
    pclsObj=NULL;
    }
    pEnumerator->Release();
    pEnumerator = NULL;
            return NULL;
    }

    VARIANT vtProp;



    wchar_t *wkey = wing_str_char_to_wchar( key );


    hr = pclsObj->Get( wkey , 0, &vtProp, 0, 0);

    //wcout<<"key=>"<<wkey<<"<=="<<endl;

    char *res = NULL;
    if( SUCCEEDED( hr ) && vtProp.bstrVal )
    {
    res = wing_str_wchar_to_char( (const wchar_t*)vtProp.bstrVal );

    }else{
    //wcout<<"fail key=>"<<wkey<<endl;
    }

    VariantClear(&vtProp);

    if( pclsObj != NULL ) {
    pclsObj->Release();
    pclsObj=NULL;
    }

    return res;
    }

    int _tmain(int argc, _TCHAR* argv[])
    {
    char sql[] = "SELECT * FROM Win32_Process\0";

    //char *sql = "SELECT * FROM Win32_Processor";

    WingWmic mic;

    mic.query(sql);
    int count = 1;
    char *c = NULL;

    while( mic.next() ) {

    c = mic.get("CommandLine");
    printf("CommandLine:%ld=>%s\r\n",count,c);

    count++;
    }

    return 0;
    }

                           
    2016年8月20日 23:06

答案

  • Hi 吉利儿,

    感谢在MSDN论坛发帖。

    WingWmic 是你自己的类吗? 请提供一些具体的实现。

    你的问题出在你没有对pEnumerator进行赋值。导致空指针调用。请使用一下代码对其进行赋值或将代码添加到你的mic.query实现中。

    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
            bstr_t("WQL"), 
            bstr_t("SELECT * FROM Win32_OperatingSystem"),
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
            NULL,
            &pEnumerator);

    希望对你有所帮助。

    Best Regards,

    Sera Yu


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.

    • 已建议为答案 Baron Bi 2016年9月7日 6:33
    • 已标记为答案 Baron Bi 2016年9月7日 6:34
    2016年8月30日 7:13

全部回复

  • 读取0x...

    那个被省略的是多少?是不是 0x00000000?

    会不会是 IWbemClassObject *pclsObj = NULL; 因为没有分配内存而出错?

    开调试器看一下吧。


    另:报错的对话框内容都是可以用 Ctrl+C 完整复制的。
    • 已编辑 sgqy 2016年8月21日 5:50
    2016年8月21日 5:49
  • 以上是官方demo修改而来的,如果是未分配内存的话,按道理来说所有的都会报错,以上demo是在查询部分字段的时候会出错,比如CommandLine字段,也不是所有的都会出错!在运行一段时间之后,比如查询了40多个进城之后,然后出错了!
    2016年8月22日 0:14
  • 像这样调用

    int _tmain(int argc, _TCHAR* argv[])
    {
    char sql[] = "SELECT * FROM Win32_Process\0";
     
    //char *sql = "SELECT * FROM Win32_Processor";

    WingWmic mic;

    mic.query(sql);
    int count = 1;
    char *c = NULL;

    while( mic.next() ) {

    c = mic.get("CommandLine");
    printf("CommandLine:%ld=>%s\r\n",count,c);
    c = mic.get("Caption");
    printf("Caption:%ld=>%s\r\n",count,c);
    c = mic.get("CSCreationClassName");
    printf("CSCreationClassName:%ld=>%s\r\n",count,c);

    count++;
    }
       
    return 0;
    }

    2016年8月24日 6:18
  • Hi 吉利儿,

    感谢在MSDN论坛发帖。

    WingWmic 是你自己的类吗? 请提供一些具体的实现。

    你的问题出在你没有对pEnumerator进行赋值。导致空指针调用。请使用一下代码对其进行赋值或将代码添加到你的mic.query实现中。

    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
            bstr_t("WQL"), 
            bstr_t("SELECT * FROM Win32_OperatingSystem"),
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
            NULL,
            &pEnumerator);

    希望对你有所帮助。

    Best Regards,

    Sera Yu


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.

    • 已建议为答案 Baron Bi 2016年9月7日 6:33
    • 已标记为答案 Baron Bi 2016年9月7日 6:34
    2016年8月30日 7:13