Compartir a través de


Ejemplo: Obtención de datos WMI del equipo local

Puede usar el procedimiento y los ejemplos de código de este tema para crear una aplicación cliente WMI completa que realice la inicialización COM, se conecte a WMI en el equipo local, recupere los datos de forma semisincrónica y, a continuación, limpie. En este ejemplo se obtiene el nombre del sistema operativo en el equipo local y se muestra. Para recuperar datos de un equipo remoto, consulte ejemplo: Obtención de datos WMI desde un equipo remoto. Para obtener los datos de forma asincrónica, consulte ejemplo: Obtener datos WMI del equipo local de forma asincrónica.

El siguiente procedimiento se usa para ejecutar la aplicación WMI. Los pasos del 1 al 5 contienen todos los pasos necesarios para configurar y conectarse a WMI, y los pasos 6 y 7 son donde se consultan y reciben los datos.

  1. Inicialice parámetros COM con una llamada a CoInitializeEx.

    Para obtener más información, vea Inicializar COM para una aplicación WMI.

  2. Inicialice la seguridad del proceso COM llamando a CoInitializeSecurity.

    Para obtener más información, vea Establecer el nivel de seguridad de proceso predeterminado mediante C++.

  3. Obtenga el localizador inicial a WMI llamando a CoCreateInstance.

    Para obtener más información, vea Crear una conexión a un espacio de nombres WMI.

  4. Obtenga un puntero para IWbemServices para el espacio de nombres root\cimv2 en el equipo local llamando a IWbemLocator::ConnectServer. Para conectarse a un equipo remoto, consulte ejemplo: Obtención de datos WMI desde un equipo remoto.

    Para obtener más información, vea Crear una conexión a un espacio de nombres WMI.

  5. Establezca IWbemServices seguridad de proxy para que el servicio WMI pueda suplantar al cliente llamando a CoSetProxyBlanket.

    Para obtener más información, vea Establecer los niveles de seguridad en una conexión WMI.

  6. Use el punteroIWbemServices para realizar solicitudes de WMI. En este ejemplo se ejecuta una consulta para el nombre del sistema operativo llamando a IWbemServices::ExecQuery.

    La siguiente consulta WQL es uno de los argumentos del método.

    SELECT * FROM Win32_OperatingSystem

    El resultado de esta consulta se almacena en un puntero IEnumWbemClassObject. Esto permite recuperar los objetos de datos de la consulta de forma semisincrónica con la interfaz IEnumWbemClassObject. Para obtener más información, vea enumerar WMI. Para obtener los datos de forma asincrónica, consulte ejemplo: Obtener datos WMI del equipo local de forma asincrónica.

    Para obtener más información sobre cómo realizar solicitudes a WMI, vea Manipular información de clase e instancia, consulta de WMIy Llamar a un método.

  7. Obtenga y muestre los datos de la consulta WQL. El puntero IEnumWbemClassObject está vinculado a los objetos de datos devueltos por la consulta y los objetos de datos se pueden recuperar con el método IEnumWbemClassObject::Next. Este método vincula los objetos de datos a un puntero IWbemClassObject que se pasa al método . Use el método IWbemClassObject::Get para obtener la información deseada de los objetos de datos.

    El siguiente ejemplo de código se usa para obtener la propiedad Name del objeto de datos, que proporciona el nombre del sistema operativo.

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

    Después de almacenar el valor de la propiedad Name en el VARIANT variable vtProp, se puede mostrar al usuario.

    Para obtener más información, vea enumerar WMI.

En el ejemplo de código siguiente se recuperan datos WMI de forma semiincrónica desde un equipo 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.
 
}