Beispiel: Erstellen einer WMI-Anwendung

Sie können mithilfe des Verfahrens und der Codebeispiele in diesem Thema eine vollständige WMI-Clientanwendung erstellen, die eine COM-Initialisierung durchführt, eine Verbindung mit WMI auf dem lokalen Computer herstellt sowie Daten liest und bereinigt. Unter Herstellen einer Verbindung mit WMI auf einem Remotecomputer wird beschrieben, wie Daten von Remotecomputern abgerufen werden.

Das folgende Verfahren enthält alle Schritte, die für alle C++-WMI-Anwendungen erforderlich sind.

  1. Initialisieren Sie COM-Parameter durch einen Aufruf von CoInitializeEx.

    Weitere Informationen finden Sie unter Initialisieren von COM für eine WMI-Anwendung.

  2. Initialisieren Sie die COM-Prozesssicherheit, indem Sie CoInitializeSecurity aufrufen.

    Weitere Informationen finden Sie unter Festlegen der Standardsicherheitsstufe für Prozesse mit C++.

  3. Rufen Sie einen Zeiger auf IWbemServices für einen Namespace auf dem angegebenen Hostcomputer ab – im einfachsten Fall dem lokalen Computer –, indem Sie IWbemLocator::ConnectServer aufrufen.

    Um eine Verbindung mit einem Remotecomputer herzustellen, z. B. „Computer_A“, verwenden Sie den folgenden Objektpfadparameter:

    _bstr_t(L"\\COMPUTER_A\ROOT\\CIMV2")
    

    Weitere Informationen finden Sie unter Erstellen einer Verbindung mit einem WMI-Namespace.

  4. Legen Sie durch Aufrufen von CoSetProxyBlanket die Proxysicherheit für IWbemServices fest, damit der WMI-Dienst die Identität des Clients annehmen kann.

    Weitere Informationen finden Sie unter Festlegen der Sicherheitsstufen für eine WMI-Verbindung.

  5. Verwenden Sie den IWbemServices-Zeiger, um Anforderungen an WMI auszuführen. Sie können z. B. alle Win32_Service-Instanzen abfragen, um zu ermitteln, welche Dienste beendet sind.

    Weitere Informationen finden Sie unter Bearbeiten von Klassen- und Instanzinformationen, Abfragen von WMI und Empfangen eines WMI-Ereignisses.

  6. Bereinigen Sie Objekte und COM.

    Weitere Informationen finden Sie unter Bereinigen und Herunterfahren einer WMI-Anwendung.

Der folgende Beispielcode ist eine vollständige WMI-Clientanwendung.


#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;

    // 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.
    }

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

    // Obtain the initial locator to Windows Management
    // on a particular host computer.
    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;

    // 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"), // 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.
    }

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

    // Set the IWbemServices proxy so that impersonation
    // of the user (client) occurs.
    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.
    }


    // Use the IWbemServices pointer to make requests of WMI. 
    // Make requests here:

    // For example, query for all the running processes
    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)
        {
            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);
            
            pclsObj->Release();
            pclsObj = NULL;
        }
         
    }
 
    // Cleanup
    // ========
    
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();  
    
    CoUninitialize();

    return 0;   // Program successfully completed.
}