Advertisement

Windows客户端开发--WMI技术介绍

阅读量:
复制代码
    时光荏苒,六道轮回。
    2004年,初中,欧锦赛,希腊神话,17岁的C罗哭成了泪人!
    2016年,工作,欧洲杯,能否再让C罗哭成泪人?

希望了解计算机硬件的相关细节?我们可以通过WMI技术来获取关于计算机硬件的详细资料。

今天就作为一个引言部分来探讨什么是WMI?
Windows Management Instrumentation (WMI)是一种可扩展的系统管理基础设施,在一个统一且基于标准的基础上提供了一种统一的对象化接口。它能够通过一种标准化的方式去交互系统管理信息以及相关的WMI API接口。主要应用于系统管理应用程序开发者与管理员群体中以获取并操作系统的管理信息。

The purpose of WMI is to provide a standardized means for managing your computer system, be it a local computer or all the computers in an enterprise. In its simplest terms, management is little more than collecting data about the state of a managed object on the computer system and altering the state of the managed object by changing the data stored about the object. A managed object can be a hardware entity, such as a memory array, port, or disk drive. It can also be a software entity, such as a service, user account, or page file.

WMI is capable of managing various components within a computer system. During hard disk management, one may utilize WMI to monitor residual free space on said disk. Additionally, WMI enables remote adjustments to drive states through actions such as deleting files, modifying file security settings, or carrying out partitions and formatting operations.

WMI serves not merely as a potent instrument for gathering system data, but also stands out for its user-friendly nature. By virtue of its scripting interface, existing WMI solutions enable users from diverse professional backgrounds, including system administrators, web-designers, and skilled programmers, to harness its capabilities effectively.

WMI全称为Windows Management Instrumentation(简称Windows管理工具),作为Windows操作系统的核心组件之一,在数据管理和操作层面发挥基础作用。无论是本地计算机还是远程服务器上的资源配置与操作管理都离不开它。对于那些掌握VC或汇编语言的程序员而言,在获取诸如CPU序列号和硬盘序列号等硬件信息上相对直接;但对于像VB这样的脚本语言这类软件来说情况就复杂许多了。微软开发了WMI系统架构并为各类应用提供了一个统一的操作系统、网络及企业环境下的接口集合。这些接口使得程序无需直接调用底层Windows API即可完成各种任务从而提升了开发效率与代码可维护性。值得注意的是并非所有脚本语言都支持通过WMI访问系统信息;只有那些具备ActiveX技术能力的语言才可以实现这一功能。

先上一个官方的例子:

复制代码
    #define _WIN32_DCOM
    #include <iostream>
    using namespace std;
    #include <comdef.h>
    #include <Wbemidl.h>
    
    #pragma comment(lib, "wbemuuid.lib")
    
    int main(int argc, char **argv)
    {
    HRESULT hres;
    
    // 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 --------------------------
    
    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 -------------------------
    
    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
    
    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 (for example, 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 ----
    
    // For example, get the name of the operating system
    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);
    
    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 = NULL;
    ULONG uReturn = 0;
    
    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 
            &pclsObj, &uReturn);
    
        if(0 == uReturn)
        {
            break;
        }
    
        VARIANT vtProp;
    
        // Get the value of the Name property
        hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
        wcout << " OS Name : " << vtProp.bstrVal << endl;
        VariantClear(&vtProp);
    
        pclsObj->Release();
    }
    
    // Cleanup
    // ========
    
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    CoUninitialize();
    
    return 0;   // Program successfully completed.
    
    }

步骤如下:
启动COM组件库;
配置进程间的COM安全参数;
建立本地进程中支持的COM服务;
与指定的Windows资源管理器命名空间建立关联;
指定WMI通信的安全级别;
向目标系统发送相应的WMI请求信息;
完成所有操作后进行资源释放。

接下来的操作就是换汤不换药。

这里有个提醒:使用低成本的方法:将上面提供的示例代码复制到自己的项目中时,请养成定期进行代码审查的习惯,并去除冗余的注释信息以及空余行。

上面的代码中用到了很多api,这里不再一一赘述,请参阅msdn官方文档。

这里仅仅是个开始,接下来要发生的事儿:

1 win32控制台程序中查看计算机显卡的详细信息
2 原因何在,在GUI应用程序中使用win32控制台程序相同的方式为何未能正确获取所需的信息?
3 qt中使用WMI中遇到了哪些坑。

coming soon~~~~~

全部评论 (0)

还没有任何评论哟~