[CPP|WMI] Pierwszy program

W tym wpisie stworzymy pierwszy prosty program w C++ z użyciem biblioteki WMI.

#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>

#pragma comment(lib, "wbemuuid.lib")

int main() {

    HRESULT hres;

    // Inicjalizacja COM
    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    
    if(FAILED(hres)) {
    
        std::cout << "Nie można zainicjalizować COM!" << std::endl;
        
        return 1;
        
    }

    // Utworzenie sesji WMI
    IWbemLocator* pLoc = 0;
    hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
    
    if(FAILED(hres)) {
    
        std::cout << "Nie można utworzyć sesji WMI!" << std::endl;
        
        CoUninitialize();
        
        return 1;
        
    }

    // Połączenie z lokalnym przestrzenią nazw WMI
    IWbemServices* pSvc = 0;
    hres = pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);
    
    if(FAILED(hres)) {
    
        std::cout << "Nie można połączyć się z przestrzenią nazw WMI!" << std::endl;
        
        pLoc->Release();
        CoUninitialize();
        
        return 1;
        
    }

    // Ustawienie zabezpieczeń dla sesji WMI
    hres = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
    
    if(FAILED(hres)) {
    
        std::cout << "Nie można ustawić zabezpieczeń dla sesji WMI" << std::endl;
        
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        
        return 1;
        
    }

    // Wykonanie zapytania WMI
    IEnumWbemClassObject* pEnumerator = 0;
    hres = pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM Win32_ComputerSystem"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
    
    if(FAILED(hres)) {
    
        std::cout << "Nie można wykonać zapytania WMI" << std::endl;
        
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        
        return 1;
        
    }

    // Pobranie wyników zapytania WMI
    IWbemClassObject* pclsObj = 0;
    ULONG uReturn = 0;
    
    while(pEnumerator) {
    
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
        
        if(0 == uReturn) {
        
            break;
            
        }

        VARIANT vtProp;
        hr = pclsObj->Get(L"TotalPhysicalMemory", 0, &vtProp, 0, 0);
        
        std::cout << "Zainstalowana pamięć RAM: " << vtProp.llVal / 1024 / 1024 << " MB" << std::endl;
        
        VariantClear(&vtProp);

        pclsObj->Release();
        
    }

    // Zwolnienie zasobów
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    CoUninitialize();

    return 0;
    
}

Jak widać na powyższym przykładzie, pobierający i wyświetlający informację TYLKO o rozmiarze pamięci RAM program jest dość obszerny pod względem kodu. Można sobie wyobrazić ile linii kodu trzeba byłoby napisać w celu pobrania więcej informacji o systemie lub sprzęcie. Aby to uprościć i zaoszczędzić sobie powtarzania tego samego fragmentu kodu, można stworzyć nakładkę z funkcją tworzącą zapytanie WMI. Można w tym celu wykorzystać szablon. Rozwiązanie takie pozwoli trzymać cały kod do obsługi połączenia i zapytania WMI w jednym pliku.

Komentarze

Popular

[C++] Jak obliczyć pole i obwód trapezu?

[PHP] Jak pobrać adres strony?

[HTML] Jak wyśrodkować tekst?