About WMI query using COM under ARX

About WMI query using COM under ARX

7598165
Advocate Advocate
712 Views
5 Replies
Message 1 of 6

About WMI query using COM under ARX

7598165
Advocate
Advocate

About WMI query using COM under ARX:

 

 

void XdDbUtils::InitializeCOM() {
    adsout << "Initializing COM library...";
    HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres)) {
        adsout << "Failed to initialize COM library. Error code = 0x"; // << std::hex << hres;
        exit(1); // Program termination
    }
    adsout << "COM library initialized successfully";
}

void XdDbUtils::InitializeSecurity() {
    adsout << "Initializing security...";
    HRESULT hres = CoInitializeSecurity(
        NULL,
        -1,                          // Number of COM authentication services
        NULL,                        // COM authentication service list
        NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication level
        RPC_C_IMP_LEVEL_IMPERSONATE, // Impersonation level
        NULL,                        // Authentication information
        EOAC_NONE,                   // Additional capabilities
        NULL                         // Reserved
    );

    if (FAILED(hres)) {
        adsout << "Failed to initialize security. Error code = 0x"; // << std::hex << hres;
        CoUninitialize();
        exit(1); // Program termination
    }
    adsout << "Security initialized successfully";
}

IWbemServices* XdDbUtils::InitializeWMI() {
    adsout << "Creating IWbemLocator object...";
    IWbemLocator* pLoc = NULL;
    HRESULT hres = CoCreateInstance(
        CLSID_WbemLocator,
        0,
        CLSCTX_INPROC_SERVER,
        IID_IWbemLocator,
        (LPVOID*)&pLoc);

    if (FAILED(hres)) {
        adsout << "Failed to create IWbemLocator object. Error code = 0x"; // << std::hex << hres;
        CoUninitialize();
        exit(1); // Program termination
    }
    adsout << "IWbemLocator object created successfully";

    adsout << "Connecting to WMI namespace...";
    IWbemServices* pSvc = NULL;
    hres = pLoc->ConnectServer(
        _bstr_t(L"ROOT\\CIMV2"), // WMI namespace
        NULL,                    // Username
        NULL,                    // Password
        0,                       // Locale
        NULL,                    // Security flags
        0,                       // Authority
        0,                       // Context object
        &pSvc                    // IWbemServices pointer
    );

    if (FAILED(hres)) {
        adsout << "Could not connect to WMI namespace. Error code = 0x"; // << std::hex << hres;
        pLoc->Release();
        CoUninitialize();
        return NULL; // Return NULL on failure
    }
    adsout << "Connected to WMI namespace successfully";

    adsout << "Setting proxy blanket...";
    hres = CoSetProxyBlanket(
        pSvc,                        // Proxy
        RPC_C_AUTHN_WINNT,           // Authentication service
        RPC_C_AUTHZ_NONE,            // Authorization service
        NULL,                        // Server principal name
        RPC_C_AUTHN_LEVEL_CALL,      // Authentication level
        RPC_C_IMP_LEVEL_IMPERSONATE, // Impersonation level
        NULL,                        // Client identity
        EOAC_NONE                    // Additional capabilities
    );

    if (FAILED(hres)) {
        adsout << "Could not set proxy blanket. Error code = 0x"; // << std::hex << hres;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return NULL; // Return NULL on failure
    }
    adsout << "Proxy blanket set successfully";

    pLoc->Release();
    return pSvc;
}

std::string XdDbUtils::ExecuteQuery(IWbemServices* pSvc) {
    adsout << "Executing WMI query...";
    IEnumWbemClassObject* pEnumerator = NULL;
    HRESULT hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        bstr_t("SELECT * FROM Win32_Processor"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);

    if (FAILED(hres)) {
        adsout << "WMI query failed. Error code = 0x"; // << std::hex << hres;
        return "";
    }
    adsout << "WMI query executed successfully";

    IWbemClassObject* pclsObj = NULL;
    ULONG uReturn = 0;
    std::string cpuModel;

    while (pEnumerator) {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

        if (0 == uReturn) {
            break;
        }

        VARIANT vtProp;
        hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
        if (SUCCEEDED(hr)) {
            cpuModel = _bstr_t(vtProp.bstrVal);
            adsout << "CPU Model found: " << cpuModel;
        }
        VariantClear(&vtProp);
        pclsObj->Release();
    }

    pEnumerator->Release();
    return cpuModel;
}

std::string XdDbUtils::QueryCPUModel() {
    std::string cpuModel;
    adsout << "Starting QueryCPUModel()";
    InitializeCOM();
    InitializeSecurity();
    IWbemServices* pSvc = InitializeWMI();
    if (pSvc) {
        adsout << "WMI service initialized successfully";
        cpuModel = ExecuteQuery(pSvc);
        pSvc->Release();
    } else {
        adsout << "Failed to initialize WMI service";
    }
    CoUninitialize();
    adsout << "\nQueryCPUModel() finished";
    return cpuModel;
}

 

 

USE:

 

 

std::string CPU= XdDbUtils::QueryCPUModel();

 

 

ACAD crashes and exits,

 

After debugging, I found that the program crashed when it reached InitializeCOM().
Can you please tell me how to solve this problem? 

0 Likes
713 Views
5 Replies
Replies (5)
Message 2 of 6

daniel_cadext
Advisor
Advisor

CoInitializeEx(0, COINIT_MULTITHREADED);

Looks wrong, maybe just use

CoInitialize(NUL) or

CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 3 of 6

daniel_cadext
Advisor
Advisor

Also, why not use win32? COM and C++ is so eeewww

 

GetSystemInfo

https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 4 of 6

7598165
Advocate
Advocate

Thank you,
Querying the CPU is just to test whether WMI query can be used in AUTOCAD
Other things, I want to query in the future, for example, which process opened a file for reading and writing, etc.

0 Likes
Message 5 of 6

7598165
Advocate
Advocate

Thank you,
After changing to single thread, InitializeCOM() can be executed correctly,
but when executing InitializeSecurity(); AUTOCAD crashes and exits

0 Likes
Message 6 of 6

daniel_cadext
Advisor
Advisor

that’s because you’re telling it to crash with the line

exit(1); // Program termination

you should handle this more gracefully, also you need to check the HRESULT to find out why

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes