Question

Deos anyone know a way, in C++, to get a complete list of every property available within a given WMI class? I've found some similar questions here on SO, but they all use Powershell, VB, or C#.

Was it helpful?

Solution

You can use the GetObject method to get an instance to the WMI Class and using the GetNames method you can retrieve the properties names.

Try this sample.

#include "stdafx.h"
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>
# pragma comment(lib, "wbemuuid.lib")

#pragma argsused
int main(int argc, char* argv[])
{
    BSTR strNetworkResource;
    //To use a WMI remote connection set localconn to false and configure the values of the pszName, pszPwd and the name of the remote machine in strNetworkResource
    bool localconn = true;  
    strNetworkResource = localconn ?  L"\\\\.\\root\\CIMV2" : L"\\\\remote--machine\\root\\CIMV2";

    // Initialize COM. ------------------------------------------

    HRESULT hres;
    hres =  CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres))
    {
        cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl;
        cout << _com_error(hres).ErrorMessage() << endl;
        cout << "press enter to exit" << endl;
        cin.get();      
        return 1;                  // Program has failed.
    }

    // 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;
        cout << _com_error(hres).ErrorMessage() << endl;
        CoUninitialize();
        cout << "press enter to exit" << endl;
        cin.get();      
        return 1;                    // Program has failed.
    }

    // 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;
        cout << _com_error(hres).ErrorMessage() << endl;
        CoUninitialize();       
        cout << "press enter to exit" << endl;
        cin.get();      
        return 1;                 // Program has failed.
    }

    // Connect to WMI through the IWbemLocator::ConnectServer method

    IWbemServices *pSvc = NULL;


        hres = pLoc->ConnectServer(
             _bstr_t(strNetworkResource),      // 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 (e.g. Kerberos)
             0,                       // Context object
             &pSvc                    // pointer to IWbemServices proxy
             );

    if (FAILED(hres))
    {
        cout << "Could not connect. Error code = 0x" << hex << hres << endl;    
        cout << _com_error(hres).ErrorMessage() << endl;
        pLoc->Release();
        CoUninitialize();
        cout << "press enter to exit" << endl;
        cin.get();          
        return 1;                // Program has failed.
    }

    cout << "Connected to root\\CIMV2 WMI namespace" << endl;

    // 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;
        cout << _com_error(hres).ErrorMessage() << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        cout << "press enter to exit" << endl;
        cin.get();      
        return 1;               // Program has failed.
    }

    // Use the IWbemServices pointer to make requests of WMI ----
    IWbemClassObject* pClass = NULL;
    hres = pSvc->GetObject(L"Win32_Process", 0, NULL, &pClass, NULL);

    if (FAILED(hres))
    {
        cout << "GetObject failed" << " Error code = 0x"    << hex << hres << endl;
        cout << _com_error(hres).ErrorMessage() << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        cout << "press enter to exit" << endl;
        cin.get();      
        return 1;               // Program has failed.
    }

    SAFEARRAY *psaNames = NULL;
    hres = pClass->GetNames(
        NULL, 
        WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY, 
        NULL, 
        &psaNames);


    if (FAILED(hres))
    {
        cout << "GetNames failed" << " Error code = 0x" << hex << hres << endl;
        cout << _com_error(hres).ErrorMessage() << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        cout << "press enter to exit" << endl;
        cin.get();      
        return 1;               // Program has failed.
    }


   // Get the number of properties.
   long lLower, lUpper; 
   BSTR PropName = NULL;
   SafeArrayGetLBound(psaNames, 1, &lLower);
   SafeArrayGetUBound(psaNames, 1, &lUpper);

        for (long i = lLower; i <= lUpper; i++) 
        {
            // Get this property.
            hres = SafeArrayGetElement(
                psaNames, 
                &i, 
                &PropName);

                wcout << PropName<< endl;
                SysFreeString(PropName);
        }

    SafeArrayDestroy(psaNames);
    ULONG uReturn = 0;


    pSvc->Release();
    pLoc->Release();

    CoUninitialize();
    cout << "press enter to exit" << endl;
    cin.get();
    return 0;   // Program successfully completed.
}

OTHER TIPS

You use IWbemClassObject::GetNames to get a list of properties after getting a class instance from a WMI query or enumeration.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top