Udostępnij przez


Przykład: pobieranie danych usługi WMI z komputera lokalnego

Możesz użyć procedury i przykładów kodu w tym temacie, aby utworzyć pełną aplikację kliencką usługi WMI, która wykonuje inicjowanie modelu COM, łączy się z usługą WMI na komputerze lokalnym, pobiera dane częściowo zsynchronizowane, a następnie czyści. Ten przykład pobiera nazwę systemu operacyjnego na komputerze lokalnym i wyświetla go. Aby pobrać dane z komputera zdalnego, zobacz Przykład: pobieranie danych WMI z komputera zdalnego. Aby uzyskać dane asynchronicznie, zobacz Przykład: pobieranie danych WMI z komputera lokalnego asynchronicznie.

Poniższa procedura służy do wykonywania aplikacji WMI. Kroki od 1 do 5 zawierają wszystkie kroki wymagane do skonfigurowania usługi WMI i nawiązania połączenia z usługą WMI, a kroki 6 i 7 to miejsce, w których dane są wysyłane i odbierane.

  1. Zainicjuj parametry MODELU COM za pomocą wywołania polecenia CoInitializeEx.

    Aby uzyskać więcej informacji, zobacz Inicjowanie modelu COM dla aplikacji WMI.

  2. Zainicjuj zabezpieczenia procesu COM, wywołując CoInitializeSecurity.

    Aby uzyskać więcej informacji, zobacz Ustawianie domyślnego poziomu zabezpieczeń procesu przy użyciu języka C++.

  3. Uzyskaj początkowy lokalizator do usługi WMI, wywołując CoCreateInstance.

    Aby uzyskać więcej informacji, zobacz Tworzenie połączenia z przestrzenią nazw usługi WMI.

  4. Uzyskaj wskaźnik IWbemServices dla przestrzeni nazw root\cimv2 na komputerze lokalnym, wywołując IWbemLocator::ConnectServer. Aby nawiązać połączenie z komputerem zdalnym, zobacz Przykład: Pobieranie danych WMI z komputera zdalnego.

    Aby uzyskać więcej informacji, zobacz Tworzenie połączenia z przestrzenią nazw usługi WMI.

  5. Ustaw zabezpieczenia serwera proxy IWbemServices, aby usługa WMI mogła personifikować klienta, wywołując coSetProxyBlanket.

    Aby uzyskać więcej informacji, zobacz Ustawianie poziomów zabezpieczeń w połączeniu usługi WMI.

  6. Użyj wskaźnika IWbemServices, aby wysyłać żądania usługi WMI. W tym przykładzie jest wykonywane zapytanie dotyczące nazwy systemu operacyjnego przez wywołanie IWbemServices::ExecQuery.

    Następujące zapytanie WQL jest jednym z argumentów metody.

    SELECT * FROM Win32_OperatingSystem

    Wynik tego zapytania jest przechowywany w wskaźniku IEnumWbemClassObject. Dzięki temu obiekty danych z zapytania mogą być pobierane częściowo za pomocą interfejsu IEnumWbemClassObject. Aby uzyskać więcej informacji, zobacz Wyliczanie usługi WMI. Aby uzyskać dane asynchronicznie, zobacz Przykład: pobieranie danych WMI z komputera lokalnego asynchronicznie.

    Aby uzyskać więcej informacji na temat wysyłania żądań do usługi WMI, zobacz Manipulowanie informacjami o klasach i wystąpieniach, wykonywanie zapytań w usłudze WMIi Wywoływanie metody.

  7. Pobierz i wyświetl dane z zapytania WQL. Wskaźnik IEnumWbemClassObject jest połączony z obiektami danych zwracanymi przez zapytanie, a obiekty danych można pobrać za pomocą metody IEnumWbemClassObject::Next. Ta metoda łączy obiekty danych z wskaźnikiem IWbemClassObject przekazywanym do metody . Użyj metody IWbemClassObject::Get, aby uzyskać żądane informacje z obiektów danych.

    Poniższy przykład kodu służy do pobierania właściwości Name z obiektu danych, który udostępnia nazwę systemu operacyjnego.

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

    Po zapisaniu wartości właściwości Name w VARIANT zmiennej vtProp można wyświetlić użytkownikowi.

    Aby uzyskać więcej informacji, zobacz Wyliczanie usługi WMI.

Poniższy przykład kodu pobiera dane usługi WMI częściowo zsynchronizowane z komputera lokalnego.

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