Share via


Beispiel: Abrufen von WMI-Daten vom lokalen Computer

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, Daten semisynchron abruft und dann bereinigt. In diesem Beispiel wird der Name des Betriebssystems auf dem lokalen Computer abgerufen und angezeigt. Informationen zum Abrufen von Daten von einem Remotecomputer finden Sie unter Beispiel: Abrufen von WMI-Daten von einem Remotecomputer. Informationen zum asynchronen Abrufen der Daten finden Sie unter Beispiel: Asynchrones Abrufen von WMI-Daten vom lokalen Computer.

Das folgende Verfahren wird zur Ausführung der WMI-Anwendung verwendet. Die Schritte 1 bis 5 enthalten alle Schritte, die zum Einrichten und Herstellen einer Verbindung mit WMI erforderlich sind, und in den Schritten 6 und 7 werden Daten abgefragt und empfangen.

  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 Sicherheitsstufe für Standardprozesse mit C++.

  3. Rufen Sie den anfänglichen Locator in WMI ab, indem Sie CoCreateInstance aufrufen.

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

  4. Rufen Sie einen Zeiger auf IWbemServices für den Namespace root\cimv2 auf dem lokalen Computer ab, indem Sie IWbemLocator::ConnectServer aufrufen. Informationen zum Herstellen einer Verbindung mit einem Remotecomputer finden Sie unter Beispiel: Abrufen von WMI-Daten von einem Remotecomputer.

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

  5. Legen Sie die Proxysicherheit für IWbemServices fest, damit der WMI-Dienst die Identität des Clients annehmen kann, indem CoSetProxyBlanket aufgerufen wird.

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

  6. Verwenden Sie den IWbemServices-Zeiger, um Anforderungen an WMI auszuführen. In diesem Beispiel wird eine Abfrage für den Namen des Betriebssystems ausgeführt, indem IWbemServices::ExecQuery aufgerufen wird.

    Die folgende WQL-Abfrage ist eines der Methodenargumente.

    SELECT * FROM Win32_OperatingSystem

    Das Ergebnis dieser Abfrage wird in einem Zeiger IEnumWbemClassObject gespeichert. Dadurch können die Datenobjekte aus der Abfrage halbsynchron mit der Schnittstelle IEnumWbemClassObject abgerufen werden. Weitere Informationen finden Sie unter WMI-Enumeration. Informationen zum asynchronen Abrufen der Daten finden Sie unter Beispiel: Asynchrones Abrufen von WMI-Daten vom lokalen Computer.

    Weitere Informationen zum Erstellen von Anforderungen an WMI finden Sie unter Bearbeiten von Klassen- und Instanzinformationen, Abfragen von WMI und Aufrufen einer Methode.

  7. Rufen Sie die Daten aus der WQL-Abfrage ab, und zeigen Sie sie an. Der Zeiger IEnumWbemClassObject ist mit den von der Abfrage zurückgegebenen Datenobjekten verknüpft, und die Datenobjekte können mit der Methode IEnumWbemClassObject::Next abgerufen werden. Diese Methode verknüpft die Datenobjekte mit einem Zeiger IWbemClassObject, der an die Methode übergeben wird. Verwenden Sie die IWbemClassObject::Get-Methode, um die gewünschten Informationen aus den Datenobjekten abzurufen.

    Im folgenden Codebeispiel wird die Name-Eigenschaft aus dem Datenobjekt abgerufen, das den Namen des Betriebssystems bereitstellt.

    VARIANT vtProp;
    VariantInit(&vtProp);
    // Get the value of the Name property
    hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
    

    Nachdem der Wert der Name-Eigenschaft in der VARIANT-Variablen vtProp gespeichert wurde, kann er dem Benutzer angezeigt werden.

    Weitere Informationen finden Sie unter WMI-Enumeration.

Im folgenden Codebeispiel werden WMI-Daten semisynchron von einem lokalen Computer abgerufen.

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

        VariantInit(&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.
 
}