首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

关于C++ 访问WMI 程序解决思路

2013-01-01 
关于C++ 访问WMI 程序我自己写了一个C++程序 (vs2010),老是连接不上Server呢 怎也找不到原因。下面的if语句

关于C++ 访问WMI 程序
我自己写了一个C++程序 (vs2010),老是连接不上Server呢 怎也找不到原因。

下面的if语句里 执行完 不等于S_OK  导致下面的语句执行不了
     string wsNamespace = ("root\\cimv2");
     if(pWbemLocator->ConnectServer((BSTR)&wsNamespace,NULL,NULL,NULL,0,NULL,NULL,&pWbemServices) ==S_OK)

然后我在网上 找了一段代码复制下来,还是执行不了 也是在ConnectServer 这里卡住了,我修改的唯一的地方就是  

定义了string 类型的namespace  然后 在函数参数里强制转换成BSTR类型 跟上面的一样

网上复制的代码 如下:
//

#include "stdafx.h"
#include<iostream>
#include <Wbemidl.h>
# pragma comment(lib, "wbemuuid.lib")

using namespace std;

//第一步:初始化COM前面已经讲过,WMI是基于COM(组件对象模型)的,所以在使用WMI前,我们必须首先初始化COM。这里主要用到两个函数
int GetInfo()
{
    HRESULT hres;

    //初始化 COM.

    hres =  CoInitializeEx(0, COINIT_MULTITHREADED);

    if (FAILED(hres))

    {

        cout << "Failed to initialize COM library. "

            << "Error code = 0x"

            << hex << hres << endl;

        return 1;              // Program has failed.

    } 

    // 设置进程安全级别

    hres =  CoInitializeSecurity(

        NULL,    

        -1,      // COM negotiates service                 

        NULL,    // Authentication services

        NULL,    // Reserved

        RPC_C_AUTHN_LEVEL_DEFAULT,    // authentication

        RPC_C_IMP_LEVEL_IMPERSONATE,  // Impersonation

        NULL,             // Authentication info

        EOAC_NONE,        // Additional capabilities

        NULL              // Reserved

        );                     

    if (FAILED(hres))

    {
        cout << "Failed to initialize security. "
            << "Error code = 0x"
            << hex << hres << endl;
        CoUninitialize();


        return 1;          // Program has failed.
    }

//
//第二步:创建一个WMI命名空间连接。
//
//WMI最大特点就是使用了统一的命名空间

//创建一个CLSID_WbemLocator对象

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

    if (FAILED(hres))
    {
        cout << "Failed to create IWbemLocator object. "
            << "Error code = 0x"
            << hex << hres << endl;

        CoUninitialize();

        return 1;       // Program has failed.
    }

    IWbemServices *pSvc = 0;

    //使用pLoc连接到” root\cimv2” 并把pSvc的指针也搞定了

    string NameSpace = "ROOT\\CIMV2";//这里我自己定义的string类型 在下面强制转换成BSTR类型

    hres = pLoc->ConnectServer(
        (BSTR)&NameSpace, // WMI namespace
        NULL,                    // User name
        NULL,                    // User password
        0,                       // Locale
        NULL,                    // Security flags                
        0,                       // Authority      
        0,                       // Context object
        &pSvc                    // IWbemServices proxy
        );                              

    if (FAILED(hres))
    {
        cout << "Could not connect. Error code = 0x"


            << hex << hres << endl;

        pLoc->Release();    

        CoUninitialize();

        return 1;                // Program has failed.

    }

     //已经连接到WMI了

    cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;

//第三步:设置连接的安全级别。
//
//    为什么要这么做?我也不清楚,MS说要这样那就这样吧:)
//
    hres = CoSetProxyBlanket(

       pSvc,                         // the proxy to set

       RPC_C_AUTHN_WINNT,            // authentication service

       RPC_C_AUTHZ_NONE,             // authorization service

       NULL,                         // Server principal name

       RPC_C_AUTHN_LEVEL_CALL,       // authentication level

       RPC_C_IMP_LEVEL_IMPERSONATE,  // impersonation level

       NULL,                         // client identity

       EOAC_NONE                     // proxy capabilities    

    );

 

    if (FAILED(hres))

    {

        cout << "Could not set proxy blanket. Error code = 0x"

             << hex << hres << endl;

        pSvc->Release();

        pLoc->Release();    

        CoUninitialize();

        return 1;               // Program has failed.

    }

//第四步:执行你的代码,达成你的目的。
//
//这里一不小心就要引入WQL这个概念了。
//
//   WQL就是WMI中的查询语言,WQL的全称是WMI Query Language,简称为WQL,翻译成中文好像可以成为Windows管理规范查询语言。熟悉SQL语言的朋友会感觉它和SQL非常相似。
//
// 
//
//WQL其实非常简单,它有如下特点:
//
//1、每个WQL语句必须以SELECT开始;
//
//2、SELECT后跟你需要查询的属性名(我刚才对应SQL将其称之为字段名了),也可以像SQL一样,以*表示返回所有属性值;
//
//3、FROM关键字;
//
//4、你要查询的类的名字;

//这里是列出正在运行的进程的例子

//为了接收结果,你必须定义一个枚举对象



    IEnumWbemClassObject* pEnumerator = NULL;

string Lan = "WQL";
string SelectStr = "SELECT * FROM Win32_Process";//这里也是string转换BSTR

    hres = pSvc->ExecQuery(

        (BSTR)&Lan,

        (BSTR)&SelectStr,

        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,

        NULL,

        &pEnumerator); 

    if (FAILED(hres))
    {
        cout << "Query for processes failed. "
             << "Error code = 0x"
             << hex << hres << endl;

        pSvc->Release();

        pLoc->Release();    

        CoUninitialize();

        return 1;               // Program has failed.

    }

    else

    {

        IWbemClassObject *pclsObj;

        ULONG uReturn = 0;

  

        while (pEnumerator)

        {

            // 推出下一个对象

hres = pEnumerator->Next(WBEM_INFINITE, 1,

                &pclsObj, &uReturn);

              //没有东西了就跳出去吧

            if(0 == uReturn)

            {

                break;

            }

 

            VARIANT vtProp;

 

            // Get the value of the Name property

            hres = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);

            wcout << "Process Name : " << vtProp.bstrVal << endl;

            VariantClear(&vtProp);

        }

        

    }

//第五步:清除关闭你的程序。
//
//释放掉该释放的东西是个好习惯。



    pSvc->Release();

    pLoc->Release();    

CoUninitialize();
}


int _tmain(int argc, _TCHAR* argv[])
{
 GetInfo();
return 0;
}


[解决办法]
我找了份代码,用于检测网络状态的,试了下可以连接
HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);



if (FAILED(hr)) 

{       

wcout << _T("错误 :CoInitializeEx 调用失败.") << endl;   

return -1;

}



hr = CoInitializeSecurity(NULL, -1, NULL, NULL,

RPC_C_AUTHN_LEVEL_PKT_PRIVACY,

RPC_C_IMP_LEVEL_IMPERSONATE,

NULL, EOAC_SECURE_REFS, NULL);

if (FAILED(hr)) 

{       

wcout << _T("错误 :CoInitializeSecurity 调用失败.") << endl;   

return -1;

}



CComPtr<IWbemLocator> spLoc;

hr = CoCreateInstance(CLSID_WbemLocator, 

0, 

CLSCTX_INPROC_SERVER,

IID_IWbemLocator, 

(LPVOID *) &spLoc);



if (FAILED(hr)) 

{   

wcout << _T("错误 :CLSID_WbemLocator 创建是失败.") << endl;   

return -1;

}



CComPtr<IWbemServices>spSvc;



hr = spLoc->ConnectServer(L"ROOT\\WMI", NULL, NULL, 0, 0, 0, 0, &spSvc);

if (FAILED(hr)) 

{           

wcout << _T("错误 :连不上 ROOT\\WMI.") << endl;   

return -1;

}



wcout << _T("成功连接到 ROOT\\WMI.") << endl;   



CNetAptMonSink *pSink = new CNetAptMonSink;





spSvc->ExecNotificationQueryAsync(

L"WQL",

L"SELECT * FROM MSNdis_StatusMediaConnect",

0, 0, pSink);





spSvc->ExecNotificationQueryAsync(

L"WQL",

L"SELECT * FROM MSNdis_StatusMediaDisconnect",

0, 0, pSink);

热点排行