2010-06-05 4 views
4

J'ai trouvé quelques exemples d'application WMI C++ dans le site Web MSDN.QCroreApplication QApplication avec WMI

J'ai essayé la forme de code le lien ci-dessous

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

quand je copiais et exécuter l'application comme application de console win32, il a bien fonctionné.

le même code i ut dans l'application Qt,

quand on utilise QApplication AnApplication (argc, argv); dans mon code il ne fonctionne pas

Mais si j'utilise QCroreApplication anApplication (argc, argv); il fonctionne

me montre l'erreur comme "quand je change QCroreApplication à QApplication Le code source ci-dessous ne fonctionne pas et me donne l'erreur comme" Échec d'initialiser la bibliothèque COM. Code d'erreur = 0x80010106 "

Toute suggestion ou aider

#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; 
} 
//----------------------------------------------------------------------------- 

Répondre

4

L'erreur que vous recevez est dû au fait que COM est déjà initialisé. appelle QApplication OleInitialize dans son constructeur, mais QCoreApplication ne pas, donc c'est pourquoi vous obtenez le 0x80010106 d'erreur (RPC_E_CHANGED_MODE) lorsque vous utilisez QApplication. pour aller plus loin, consultez la documentation CoInitializeEx. les article suivants devraient fournir

0

plus de perspicacité. au début, je l'ai utilisé ce code

hres = CoInitializeEx(0, COINIT_MULTITHREADED); 

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

Quand j'obtiens l'erreur « Impossible d'initialiser la bibliothèque COM (0x80010106)

Je viens d'appeler OleUninitialize pour traiter OleInitialize() dans QApplication, mais qui pourrait briser certaines fonctionnalités qt.

Comme je l'ai trouvé le mieux est d'utiliser le drapeau COINIT_APARTMENTTHREADED pour CoInitializeEx

MSDN

En général, un fil qui crée une fenêtre doit utiliser le drapeau COINIT_APARTMENTTHREADED, et d'autres fils doivent utiliser COINIT_MULTITHREADED. Cependant, certains composants COM nécessitent un modèle de thread particulier. La documentation MSDN devrait vous dire quand c'est le cas.

Pour moi, il s `une magie noire, mais il m'a aidé