VC6调用WMI编程——平台搭建

wmi example

微软MSDN的一个例子在vc6下编译测试通过

#include <afx.h> //用到了CString 的 BSTR转ANSI
#define _WIN32_DCOM 

//vc6的bug.所以没用使用标准stl..
#include <iostream.h>
#include <iomanip.h>
//using namespace std;
//com组件
#include <comdef.h>
#include <Wbemidl.h>
# pragma comment(lib, "wbemuuid.lib") //链接lib

int main(int argc, char **argv)
{
    HRESULT hres; //定义COM调用的返回  HRESULT com返回类型

// Step 1: --------------------------------------------------
    // Initialize 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.
    }

// Step 2: --------------------------------------------------
    // Set general COM security levels --------------------------
    // Note: If you are using Windows 2000, you need to specify -
    // the default authentication credentials for a user by using
    // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
    // parameter of CoInitializeSecurity ------------------------
    //常规安全级别设置(不写系统会调用默认的)
    hres =  CoInitializeSecurity(
        NULL, 
        -1,                          // COM authentication
        NULL,                        // Authentication services
        NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
        RPC_C_IMP_LEVEL_IMPERSONATE, // Default 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.
    }
    
// Step 3: ---------------------------------------------------
    // Obtain the initial locator to WMI -------------------------
    //创建一个CLSID_WebmLocator对象.
    IWbemLocator *pLoc = NULL;
    hres = CoCreateInstance(
        CLSID_WbemLocator,
        0, 
        CLSCTX_INPROC_SERVER, 
        IID_IWbemLocator, (LPVOID *) &pLoc);
 
    if (FAILED(hres))
    {
        cout << "Failed to create IWbemLocator object."
            << " Err code = 0x"
            << hex << hres << endl;
        CoUninitialize();
        return 1;                 // Program has failed.
    }

// Step 4: -----------------------------------------------------
    // Connect to WMI through the IWbemLocator::ConnectServer method
    //连接WMI
    IWbemServices *pSvc = NULL;

    // Connect to the root\cimv2 namespace with
    // the current user and obtain pointer pSvc
    // to make IWbemServices calls.
    hres = pLoc->ConnectServer(
         _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
         NULL,                    // User name. NULL = current user
         NULL,                    // User password. NULL = current
         0,                       // Locale. NULL indicates current
         NULL,                    // Security flags.
         0,                       // Authority (e.g. Kerberos)
         0,                       // Context object 
         &pSvc                    // pointer to IWbemServices proxy
         );
    
    if (FAILED(hres))
    {
        cout << "Could not connect. Error code = 0x" 
             << hex << hres << endl;
        pLoc->Release();     
        CoUninitialize();
        return 1;                // Program has failed.
    }

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


// Step 5: --------------------------------------------------
    // Set security levels on the proxy -------------------------
    // 设置连接的安全级别
    hres = CoSetProxyBlanket(
       pSvc,                        // Indicates the proxy to set
       RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
       RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
       NULL,                        // Server principal name 
       RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
       RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
       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.
    }

// Step 6: --------------------------------------------------
    // Use the IWbemServices pointer to make requests of WMI ----
    //执行你的代码
    //以SELECT开头,后面跟要查询的属性名(字段名)(可使用通配符*),再跟FROM,后面跟你要查询的类的名字
    // 下面是获取操作版本信息的方式
    // For example, get the name of the operating system
    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
        bstr_t("WQL"), 
//        bstr_t("SELECT * FROM Win32_OperatingSystem"),string到com的装箱,bstr类型
        bstr_t("SELECT * FROM Win32_Process"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
        NULL,
        &pEnumerator);
    
    if (FAILED(hres))
    {
        cout << "Query for operating system name failed."
            << " Error code = 0x" 
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;               // Program has failed.
    }

// Step 7: -------------------------------------------------
    // Get the data from the query in step 6 -------------------
    //枚举查询
    IWbemClassObject *pclsObj;
    ULONG uReturn = 0;  //无符号长整
    cout<<"ProcessID  :ProcessName"<<endl;
    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 
            &pclsObj, &uReturn);

        if(0 == uReturn)
        {
            break;
        }

        VARIANT vtProp;  //Variant 是一种特殊的数据类型,除了定长String数据及用户定义类型外,可以包含任何种类的数据。Variant 也可以包含Empty、Error、Nothing及Null等特殊值。可以用VarType函数或TypeName函数来决定如何处理 Variant 中的数据。
//         // Get the value of the Name property
//         hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
//         CString str(vtProp.bstrVal);
//      //        cout << " OS Name : " << str.GetBuffer(NULL) << endl;
//         cout << " Process+++: " << str.GetBuffer(NULL) << endl;
//         //cout << " OS Name : " << vtProp.bstrVal << endl;

        // Get the value of the Name property
        hr = pclsObj->Get(L"ProcessID", 0, &vtProp, 0, 0);
        cout <<setw(10)<<(vtProp.uiVal) << ends;
                
        hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
        CString str(vtProp.bstrVal);
        cout << ":" << str.GetBuffer(NULL) << endl;

        VariantClear(&vtProp);

        pclsObj->Release();
    }

// Cleanup
    // ========
    // 不要忘记释放COM对象.
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
//MSDN例子的错误
    if(!pclsObj)
        pclsObj->Release();
    CoUninitialize();

    return 0;   // Program successfully completed.
}```

在VC6下测试,有

fatal error C1083: Cannot open include file: 'wbemidl.h': No such file or directory```
即“wbemidl.h”头文件未找到,于是乎跑到C:/下搜索该文件,发现有两处存在:
C:/Program Files/Microsoft SDKs/Windows/v5.0/Include/WbemIdl.h
C:/Program Files/Microsoft SDKs/Windows/v6.0A/Include/WbemIdl.h

查找资料发现,普遍认为不能再VC6中使用VS2008中附带的SDK,微软对VC6支持的最新的SDK版本为"PlatformSDK_2003_February"
在CSDN找到了一篇博文。提到了神奇的在微软社区一篇帖子,帖中有人给出了"PlatformSDK_2003_February"的下载地址,引用如下:

Here are the direct links to the Febuary 2003 SDK (build 5.2.3790.0):

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.1.cab 

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.2.cab

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.3.cab 

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.4.cab 


http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.5.cab 

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.6.cab 

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.7.cab 

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.8.cab 

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.9.cab 

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.10.cab 

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.11.cab 

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.12.cab 

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.13.cab 

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/PSDK-FULL.bat

http://download.microsoft.com/download/platformsdk/sdk/update/win98mexp/en-us/3790.0/FULL/Extract.exe

You must download all files in the same directory. To extract the SDK on your HDD you must use the batch file. After extracting the SDK you can install it from your extraction directory. You can also burn it on a CD or DVD.

安装完成后,在VC的Options -> Directories页面中添加相关搜索路径,再次进行编译,结果再次报错,报错信息如下:

error C2065: 'CoInitializeSecurity' : undeclared identifier
error C2065: 'EOAC_NONE' : undeclared identifier```
这次应该不能是SDK的问题了,到SDK的Include目录安装路径"C:/Program Files/Microsoft SDK/include"中,搜索文本"CoInitializeSecurity",发现其定义在"OBJBASE.H"文件中,且使用一个预编译宏控制:

if (_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)

添加一行

define _WIN32_DCOM ```

遇到错误信息

error LNK2001: unresolved external symbol __endthreadex

解决方法如下:
在做MFC程序的时候,由于不是用MFC APPWizard生成的,所以在调试的时候就出现了标题和下面所示的错误了:

error LNK2001: unresolved external symbol __endthreadex

error LNK2001: unresolved external symbol __beginthreadex

error LNK2001: unresolved external symbol _main

Debug/Hello.exe : fatal error LNK1120: 3 unresolved externals

解决方法:

1、“Project”->“settings”->“c/c++”->“Catagory” 选择“Code Generation”

  “use run-time library”选择“debug multithreaded”

    此时确定一般解决问题,也有可能出现如下问题提示:

    error LNK2001: unresolved external symbol _main

    Debug/Hello.exe : fatal error LNK1120: 1 unresolved externals

    这是由于我们的程序现在默认的是控制台应用程序,我们MFC做的是windows的应用程序,当然会产生错误了。

    此时,进行第二步操作:

2、[Project] --> [Settings] --> 选择"Link"属性页,

   在Project Options中将/subsystem:console改成/subsystem:windows

   提示:在Project Options窗口,右边滑动条向下滑动就会找到该项!

   进行以上两步操作后,问题解决!

参考:
1、Getting Information from WMI in Visual C++
http://www.codeproject.com/KB/system/Using_WMI_in_Visual_C__.aspx
2、Microsoft Platform SDK - February 2003,用VC6的不能不知道的事件
http://blog.csdn.net/citysheep/archive/2007/12/28/1996048.aspx
3、【收藏】通过 WMI 获取系统信息
http://www.zaoxue.com/article/tech-44714.htm
4、where download sdk server 2003 february edition ?
http://social.msdn.microsoft.com/Forums/zh-CN/windowssdk/thread/83205c43-ef46-447d-ae54-92bbeb543c38
5、http://blog.csdn.net/tzxx/article/details/6385292
6、http://blog.csdn.net/wangjieest/article/details/7320572

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容