2011-06-13 78 views
0

下面的代碼顯示的結果(編譯:VS 2008)奇怪的WMI查詢結果

連接到ROOT \ CIMV2 WMI命名空間

OS名稱:Microsoft Windows XP中 專業| C:\ WINDOWS | \ Device \ Harddisk0 \ Partition1

這是正確的嗎?代碼是從here複製的,並在後面的評論中進行了一些修改。與「版本」取代「名稱」示出正確的結果即5.1.2600

#define _WIN32_DCOM 

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

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

int main(int iArgCnt, char ** 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 must 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 negotiates service 
     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 local root\cimv2 namespace 
    // and obtain pointer pSvc to make IWbemServices calls. 
    hres = pLoc->ConnectServer(
     _bstr_t(L"ROOT\\CIMV2"), 
     NULL, 
     NULL, 
     0, 
     NULL, 
     0, 
     0, 
     &pSvc 
    ); 

    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 for 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_OperatingSystem"), 
     WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
     NULL, 
     &pEnumerator); 

    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. 
    } 

IWbemClassObject *pclsObj; 
    ULONG uReturn = 0; 

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

     if(0 == uReturn) 
     { 
      break; 
     } 

     VARIANT vtProp; 

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

     pclsObj->Release(); 
    } 

    // Clean up 
    //-------------------------- 
pSvc->Release(); 
    pLoc->Release(); 
    pEnumerator->Release(); 
    CoUninitialize(); 
    return 0; 
} 

回答

0

Caption」 的作品,而不是Name

1

輸出代碼假定不正確,返回BSTR值是空值終止。

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

你必須使用SysStringLen確定BSTR的真實長度,然後寫,考慮到這個輸出邏輯。

這是通過簡單的輔助類_bstr_t,它封裝了所有這些棘手的原料BSTR語義爲更傳統的C應對BSTR小號++包裝,比照std::string VS char*

+0

'「Caption」'工作而不是名字! – yolo 2011-06-14 11:23:36