Dela via


Exempel: Hämta WMI-data från den lokala datorn

Du kan använda proceduren och kodexemplen i det här avsnittet för att skapa ett fullständigt WMI-klientprogram som utför COM-initiering, ansluter till WMI på den lokala datorn, hämtar data semisynkront och sedan rensar upp. Det här exemplet hämtar namnet på operativsystemet på den lokala datorn och visar det. Information om hur du hämtar data från en fjärrdator finns i Exempel: Hämta WMI-data från en fjärrdator. Information om hur du hämtar data asynkront finns i Exempel: Hämta WMI-data från den lokala datorn asynkront.

Följande procedur används för att köra WMI-programmet. Steg 1 till och med 5 innehåller alla steg som krävs för att konfigurera och ansluta till WMI, och steg 6 och 7 är där data efterfrågas och tas emot.

  1. Initiera COM-parametrar med ett anrop till CoInitializeEx.

    Mer information finns i Initiera COM för ett WMI-program.

  2. Initiera COM-processsäkerhet genom att anropa CoInitializeSecurity.

    Mer information finns i Ange standardprocesssäkerhetsnivå med C++.

  3. Hämta den första lokaliseraren till WMI genom att anropa CoCreateInstance.

    Mer information finns i Skapa en anslutning till ett WMI-namnområde.

  4. Hämta en pekare till IWbemServices för namnområdet root\cimv2 på den lokala datorn genom att anropa IWbemLocator::ConnectServer. Information om hur du ansluter till en fjärrdator finns i Exempel: Hämta WMI-data från en fjärrdator.

    Mer information finns i Skapa en anslutning till ett WMI-namnområde.

  5. Ange IWbemServices proxysäkerhet så att WMI-tjänsten kan personifiera klienten genom att anropa CoSetProxyBlanket.

    Mer information finns i Ställa in säkerhetsnivåerna för en WMI-anslutning.

  6. Använd pekaren IWbemServices för att göra begäranden om WMI. Det här exemplet kör en fråga för namnet på operativsystemet genom att anropa IWbemServices::ExecQuery.

    Följande WQL-fråga är ett av metodargumenten.

    SELECT * FROM Win32_OperatingSystem

    Resultatet av den här frågan lagras i en IEnumWbemClassObject- pekare. På så sätt kan dataobjekten från frågan hämtas semisynkront med gränssnittet IEnumWbemClassObject. Mer information finns i Räkna upp WMI-. Information om hur du hämtar data asynkront finns i Exempel: Hämta WMI-data från den lokala datorn asynkront.

    Mer information om hur du gör förfrågningar till WMI finns i Manipulating Class and Instance Information, Querying WMIoch Calling a Method.

  7. Hämta och visa data från WQL-frågan. Pekaren IEnumWbemClassObject är länkad till dataobjekten som frågan returnerade, och dataobjekten kan hämtas med IEnumWbemClassObject::Nästa metod. Den här metoden länkar dataobjekten till en IWbemClassObject pekare som skickas till metoden. Använd metoden IWbemClassObject::Get för att hämta önskad information från dataobjekten.

    Följande kodexempel används för att hämta egenskapen Namn från dataobjektet, som innehåller namnet på operativsystemet.

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

    När värdet för egenskapen Namn har lagrats i VARIANT variabeln vtProp, kan den sedan visas för användaren.

    Mer information finns i Räkna upp WMI-.

I följande kodexempel hämtas WMI-data semisynkront från en lokal dator.

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