8 Stimmen

QCoreAnwendung QAnwendung mit WMI

Ich habe einige WMI C++ Anwendungsbeispiele auf der MSDN Website gefunden.

Ich habe den Code aus dem folgenden Link ausprobiert

http://msdn.microsoft.com/en-us/library/aa390423%28v=VS.85%29.aspx

Wenn ich die Anwendung kopiert und als Win32-Konsolenanwendung ausgeführt habe, hat sie gut funktioniert.

denselben Code, den ich in die Qt-Anwendung eingefügt habe,

Wenn ich die QApplication anApplication ( argc, argv ); in meinem Code funktioniert es nicht

Aber wenn ich die QCoreApplication anApplication ( argc, argv ); es funktioniert

zeigt mir eine Fehlermeldung wie "Wenn ich QCoreApplication in QApplication ändere, funktioniert der folgende Quellcode nicht und gibt mir die Fehlermeldung "Failed to initialize COM library. Fehlercode = 0x80010106 "

Vorschläge oder Hilfe

#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>

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

// Qt Includes
#include <QtCore>
#include <QtGui>

 //----------------------------------------------------------------------------

// Main Function
int main( int a_argc, char *a_argv[] )
//************************************
{
    // initialize the application
    QApplication anapplication( a_argc, a_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 --------------------------
    // Note: If you are using Windows 2000, you need to specify -
    // the default authentication credentials for a user by using
    // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
    // parameter of CoInitializeSecurity ------------------------

    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 (e.g. 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_USBControllerDevice"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
        NULL,
        &pEnumerator);

//ExecQuery(L"WQL", L"SELECT * FROM Win32_LogicalDisk", WBEM_FLAG_FORWARD_ONLY, NULL, &iter);

    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;
    ULONG uReturn = 0;

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

        if(FAILED(hr)||0 == uReturn)
        {
            break;
        }

        VARIANT vtProp;

        // Get the value of the Name property
        /*hr = pclsObj->Get(L"VolumeName", 0, &vtProp, 0, 0);
        wcout << " VolumeName : " << vtProp.bstrVal << endl;
        VariantClear(&vtProp);*/

        if (FAILED(pclsObj->Get(L"Antecedent", 0, &vtProp, 0, 0)))
        {
            cout<<"The specified property is not found."<<endl;
        }
        else
        {
            wcout <<vtProp.bstrVal << endl;
        }

        pclsObj->Release();
    }

    // Cleanup
    // ========

    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
   // pclsObj->Release();
    CoUninitialize();

   // return 0;   // Program successfully completed.

    //execute the application
    int anInt = anapplication.exec();

    return anInt;
}
//-----------------------------------------------------------------------------

9voto

Garett Punkte 16274

Der Fehler, den Sie erhalten, ist auf die Tatsache zurückzuführen, dass COM bereits initialisiert ist. QApplication ruft OleInitialize in seinem Konstruktor auf, QCoreApplication jedoch nicht, weshalb Sie den Fehler 0x80010106 (RPC_E_CHANGED_MODE) erhalten, wenn Sie QApplication verwenden. Für weitere Informationen lesen Sie bitte die Dokumentation für CoInitializeEx . Die folgenden Artikel sollte mehr Aufschluss geben.

2voto

Yuriy Pryyma Punkte 545

Zunächst habe ich folgenden Code verwendet

hres =  CoInitializeEx(0, COINIT_MULTITHREADED);

if (hres == RPC_E_CHANGED_MODE) {
    OleUninitialize();
    hres =  CoInitializeEx(0, COINIT_MULTITHREADED);
}

Wenn ich die Fehlermeldung "Failed to initialize COM library(0x80010106)

Ich rufe einfach OleUninitialize auf, um mit OleInitialize() in QApplication umzugehen, aber das könnte einige Qt-Funktionalität brechen.

Ich habe festgestellt, dass es am besten ist, das Flag COINIT_APARTMENTTHREADED für CoInitializeEx zu verwenden

MSDN

Im Allgemeinen sollte ein Thread, der ein Fenster erstellt, das Flag COINIT_APARTMENTTHREADED verwenden, und andere Threads sollten COINIT_MULTITHREADED verwenden. Einige COM-Komponenten erfordern jedoch ein bestimmtes Threading-Modell. Die MSDN-Dokumentation sollte Ihnen sagen, wenn dies der Fall ist.

Für mich ist es eine schwarze Magie, aber sie hat mir geholfen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X