Udostępnij za pośrednictwem


Przykład: tworzenie aplikacji WMI

W tym temacie można użyć procedury i przykładów kodu, aby utworzyć pełną aplikację kliencką usługi WMI, która wykonuje inicjowanie modelu COM, łączy się z usługą WMI na komputerze lokalnym, odczytuje niektóre dane i czyści. Nawiązywanie połączenia z usługą WMI na komputerze zdalnym opisuje sposób uzyskiwania danych z komputerów zdalnych.

Poniższa procedura obejmuje wszystkie kroki wymagane przez wszystkie aplikacje WMI języka C++.

  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 wskaźnik IWbemServices dla przestrzeni nazw na określonym komputerze hosta — komputerze lokalnym w prostym przypadku — wywołując IWbemLocator::ConnectServer.

    Aby nawiązać połączenie z komputerem zdalnym, na przykład Computer_A, użyj następującego parametru ścieżki obiektu:

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

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

  4. 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.

  5. Użyj wskaźnika IWbemServices, aby wysyłać żądania usługi WMI. Na przykład wykonywanie zapytań dotyczących wszystkich wystąpień Win32_Service w celu określenia, które usługi zostały zatrzymane.

    Aby uzyskać więcej informacji, zobacz Manipulowanie informacjami o klasach i wystąpieniach, wykonywanie zapytań dotyczących usługi WMIi odbieranie zdarzenia usługi WMI.

  6. Czyszczenie obiektów i modelu COM.

    Aby uzyskać więcej informacji, zobacz Czyszczenie i zamykanie aplikacji WMI.

Poniższy przykładowy kod to kompletna aplikacja kliencka WMI.


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