Esempio: Recupero di dati WMI dal computer locale

È possibile utilizzare la procedura e gli esempi di codice in questo argomento per creare un'applicazione client WMI completa che esegue l'inizializzazione COM, connettersi a WMI nel computer locale, recuperare i dati in modo semisynchrono e quindi eseguire la pulizia. Questo esempio ottiene il nome del sistema operativo nel computer locale e lo visualizza. Per recuperare dati da un computer remoto, vedere Esempio: Recupero di dati WMI da un computer remoto. Per ottenere i dati in modo asincrono, vedere Esempio: Recupero di dati WMI dal computer locale in modo asincrono.

Per eseguire l'applicazione WMI viene utilizzata la procedura seguente. I passaggi da 1 a 5 contengono tutti i passaggi necessari per configurare e connettersi a WMI e i passaggi 6 e 7 in cui i dati vengono sottoposti a query e ricevuti.

  1. Inizializzare i parametri COM con una chiamata a CoInitializeEx.

    Per altre informazioni, vedere Inizializzazione di COM per un'applicazione WMI.

  2. Inizializzare la sicurezza del processo COM chiamando CoInitializeSecurity.

    Per altre informazioni, vedere Impostazione del livello di sicurezza del processo predefinito tramite C++.

  3. Ottenere il localizzatore iniziale a WMI chiamando CoCreateInstance.

    Per altre informazioni, vedere Creazione di una connessione a uno spazio dei nomi WMI.

  4. Ottenere un puntatore a IWbemServices per lo spazio dei nomi root\cimv2 nel computer locale chiamando IWbemLocator::ConnectServer. Per connettersi a un computer remoto, vedere Esempio: Recupero di dati WMI da un computer remoto.

    Per altre informazioni, vedere Creazione di una connessione a uno spazio dei nomi WMI.

  5. Impostare la sicurezza proxy IWbemServices in modo che il servizio WMI possa rappresentare il client chiamando CoSetProxyBlanket.

    Per altre informazioni, vedere Impostazione dei livelli di sicurezza in una connessione WMI.

  6. Usare il puntatore IWbemServices per effettuare richieste di WMI. In questo esempio viene eseguita una query per il nome del sistema operativo chiamando IWbemServices::ExecQuery.

    La query WQL seguente è uno degli argomenti del metodo.

    SELECT * FROM Win32_OperatingSystem

    Il risultato di questa query viene archiviato in un puntatore IEnumWbemClassObject . In questo modo gli oggetti dati della query possono essere recuperati in modo semisynchronous con l'interfaccia IEnumWbemClassObject . Per altre informazioni, vedere Enumerazione WMI. Per ottenere i dati in modo asincrono, vedere Esempio: Recupero di dati WMI dal computer locale in modo asincrono.

    Per altre informazioni sull'esecuzione di richieste a WMI, vedere Modifica delle informazioni sulle classi e sull'istanza, esecuzione di query SU WMI e chiamata di un metodo.

  7. Ottenere e visualizzare i dati dalla query WQL. Il puntatore IEnumWbemClassObject è collegato agli oggetti dati restituiti dalla query e gli oggetti dati possono essere recuperati con il metodo IEnumWbemClassObject::Next . Questo metodo collega gli oggetti dati a un puntatore IWbemClassObject passato al metodo . Usare il metodo IWbemClassObject::Get per ottenere le informazioni desiderate dagli oggetti dati.

    Nell'esempio di codice seguente viene utilizzata per ottenere la proprietà Name dall'oggetto dati , che fornisce il nome del sistema operativo.

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

    Dopo aver archiviato il valore della proprietà Name nella variabile VARIANT vtProp, può essere visualizzato all'utente.

    Per altre informazioni, vedere Enumerazione WMI.

L'esempio di codice seguente recupera i dati WMI in modo semisynchronous da un computer locale.

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