• WMI编程之一:在VC中使用WMI


          经过一周的忙碌,总算是有点时间可以写一写博客了,现在就讲讲如何在VC中使用WMI。下面就分五步来构建一个简单的WMI的应用框架。

    在写程序前千万不要忘了包含头文件和链接库文件。

    #include <Wbemidl.h>

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

    之后我们可以了

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

        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.

        }

    到这里,我们就算是初始化COM完成了。下面进入下一步。

    第二步:创建一个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的指针也搞定了

        hres = pLoc->ConnectServer(

            _bstr_t(L"ROOT\\CIMV2"), // 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开始;

    2SELECT后跟你需要查询的属性名(我刚才对应SQL将其称之为字段名了),也可以像SQL一样,以*表示返回所有属性值;

    3FROM关键字;

    4、你要查询的类的名字;

     

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

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

        IEnumWbemClassObject* pEnumerator = NULL;

        hres = pSvc->ExecQuery(

            bstr_t("WQL"),

            bstr_t("SELECT * FROM Win32_Process"),

            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)

            {

                // 推出下一个对象

    res = 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();

    到这里,我们就基本完成了WMI最简单的应用框架,是不是感觉还有很多工作需要做?没关系,下次我们再介绍一个有UI的框架,以方便大家的使用。

    这里是本章的例子:https://files.cnblogs.com/hamwolf/WMIBase.zip

  • 相关阅读:
    python-字典
    C#公历转农历算法
    GridView控件显示图片
    SQLite DBHelp
    面向服务体系结构:适用于敏捷的系统
    针对 .NET 框架的安全编码指南
    Microsoft .NET Pet Shop 4
    C#.NET数据库访问类DBHelper
    Emgu CV 高斯建模
    .NET代码编写规范 整理
  • 原文地址:https://www.cnblogs.com/hamwolf/p/1931036.html
Copyright © 2020-2023  润新知