Exemple : Obtention de données WMI à partir de l’ordinateur local

Vous pouvez utiliser la procédure et les exemples de code de cette rubrique pour créer une application cliente WMI complète qui effectue l’initialisation COM, se connecte à WMI sur l’ordinateur local, récupère les données semi-synchronisées, puis nettoie. Cet exemple obtient le nom du système d’exploitation sur l’ordinateur local et l’affiche. Pour vous connecter à un ordinateur distant, consultez Exemple : Obtention de données WMI à partir d’un ordinateur distant. Pour obtenir les données de manière asynchrone, consultez Exemple : Obtention de données WMI à partir de l’ordinateur local de manière asynchrone.

La procédure suivante est utilisée pour exécuter l’application WMI. Les étapes 1 à 5 contiennent toutes les étapes requises pour configurer et se connecter à WMI, et les étapes 6 et 7 sont l’endroit où les données sont interrogées et reçues.

  1. Initialisez les paramètres COM avec un appel à CoInitializeEx.

    Pour plus d’informations, consultez Initialisation de COM pour une application WMI.

  2. Initialisez la sécurité des processus COM en appelant CoInitializeSecurity.

    Pour plus d’informations, consultez Définition du niveau de sécurité de processus par défaut à l’aide de C++.

  3. Obtenez le localisateur initial sur WMI en appelant CoCreateInstance.

    Pour plus d’informations, consultez Création d’une connexion à un espace de noms WMI.

  4. Obtenez un pointeur vers IWbemServices pour l’espace de noms root\cimv2 sur l’ordinateur local en appelant IWbemLocator::ConnectServer. Pour vous connecter à un ordinateur distant, consultez Exemple : Obtention de données WMI à partir d’un ordinateur distant.

    Pour plus d’informations, consultez Création d’une connexion à un espace de noms WMI.

  5. Définissez la sécurité du proxy IWbemServices afin que le service WMI puisse emprunter l’identité du client en appelant CoSetProxyBlanket.

    Pour plus d’informations, consultez Définition des niveaux de sécurité sur une connexion WMI.

  6. Utilisez le pointeur IWbemServices pour effectuer des requêtes à WMI. Cet exemple exécute une requête pour le nom du système d’exploitation en appelant IWbemServices::ExecQuery.

    La requête WQL suivante est l’un des arguments de méthode.

    SELECT * FROM Win32_OperatingSystem

    Le résultat de cette requête est stocké dans un pointeur IEnumWbemClassObject . Cela permet de récupérer les objets de données de la requête de manière semi-synchrone avec l’interface IEnumWbemClassObject. Pour plus d’informations, consultez Énumération de WMI. Pour obtenir les données de manière asynchrone, consultez Exemple : Obtention de données WMI à partir de l’ordinateur local de manière asynchrone.

    Pour plus d’informations sur l’envoi de requêtes à WMI, consultez Manipulation d’informations de classe et d’instance, Interrogation de WMIet Appel d’une méthode.

  7. Obtenez et affichez les données de la requête WQL. Le pointeur IEnumWbemClassObject est lié aux objets de données retournés par la requête, et les objets de données peuvent être récupérés avec la méthode IEnumWbemClassObject::Next. Cette méthode lie les objets de données à un pointeur IWbemClassObject qui est passé dans la méthode. Utilisez la méthode IWbemClassObject::Get pour obtenir les informations souhaitées à partir des objets de données.

    L’exemple de code suivant est utilisé pour obtenir la propriété Name à partir de l’objet de données, qui fournit le nom du système d’exploitation.

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

    Une fois la valeur de la propriété Name stockée dans la variable VARIANT vtProp, elle peut être affichée à l’utilisateur.

    Pour plus d’informations, consultez Énumération de WMI.

L’exemple de code suivant récupère des données WMI semi-synchronisées à partir d’un ordinateur local.

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