共用方式為


存取 WMI 預先安裝的效能類別

WMI 存放庫包含所有效能連結庫物件的預安裝效能類別。 例如,原始數據效能類別的實例 Win32_PerfRawData_PerfProc_Process 代表進程。 此性能物件會顯示在 System Monitor 中做為 Process 物件。

Win32_PerfRawData_PerfProc_ProcessPageFaultsPerSec 屬性代表程序的每秒頁面錯誤性能計數器。 Win32_PerfFormattedData 類別包含系統監視器中顯示的匯出數據值(Perfmon.exe)。 Win32_PerfFormattedData_PerfProc_ProcessPageFaultsPerSec 屬性值與系統監視器中顯示的相同。

使用適用於 WMI COM API 或適用於 WMI 腳本 API,透過 性能計數器類別存取效能數據。 在這兩種情況下,都需要 重新整理器 物件,才能取得每個數據範例。 如需有關使用重新整理程式和存取性能類別的詳細資訊及程式碼範例,請參閱 WMI 工作:性能監視。 如需詳細資訊,請參閱 在腳本中存取效能數據。

從C++存取效能數據

下列C++程式代碼範例會使用性能計數器提供者來存取預先定義的高效能類別。 它會建立重新整理器物件,並將 物件新增至重新整理器。 對像是 Win32_PerfRawData_PerfProc_Process 實例,可監視特定進程的效能。 程序代碼只會讀取進程物件中的一個計數器屬性,VirtualBytes 屬性。 程序代碼需要下列參考和 #include 語句才能正確編譯。

#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")

下列程式示範如何從C++中的高效能提供者存取數據。

若要在 C++ 中從高效能的供應商存取資料

  1. 使用呼叫 IWbemLocator::ConnectServer CoSetProxyBlanket來建立 WMI 命名空間的連線,並設定 WMI 安全性。

    此步驟是建立任何 WMI 用戶端應用程式的標準步驟。 如需詳細資訊,請參閱 使用 C++建立 WMI 應用程式。

  2. 使用 CoCreateInstance 搭配 CLSID_WbemRefresher 建立重新整理器物件。 透過 QueryInterface 方法,要求 IWbemConfigureRefresher 介面。 透過 QueryInterface 方法,要求 IWbemRefresher 介面。

    IWbemRefresher 介面是 WMI Refresher 物件的主要介面。

    下列C++程式代碼範例示範如何擷取 IWbemConfigureRefresher

    IWbemRefresher* pRefresher = NULL;
    
    HRESULT hr = CoCreateInstance(
        CLSID_WbemRefresher,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_IWbemRefresher,
        (void**) &pRefresher);
    
    IWbemConfigureRefresher* pConfig = NULL;
    
    pRefresher->QueryInterface( 
        IID_IWbemConfigureRefresher,
        (void**) &pConfig
      );
    
  3. 透過呼叫 IWbemConfigureRefresher::AddObjectByPath 方法,將 物件新增至重新整理器。

    當您將物件新增至重新整理器時,每當呼叫 IWbemRefresher::Refresh 方法時,WMI 就會重新整理物件。 您加入的物件會在其類別限定符中指定提供者。

    下列C++程式代碼範例示範如何呼叫 AddObjectByPath

    IWbemClassObject* pObj = NULL;
    IWbemServices* pNameSpace = NULL;
    
    // Add the instance to be refreshed.
    hr = pConfig->AddObjectByPath(
         pNameSpace,
         L"Win32_PerfRawData_PerfProc_Process.Name=\"WINWORD\"",
         0L,
         NULL,
         &pObj,
         NULL
    );
    if (FAILED(hr))
    {
       cout << "Could not add object. Error code: 0x"
            << hex << hr << endl;
       pNameSpace->Release();
       return hr;
    }
    
  4. 若要設定更快速地存取物件,請透過 IWbemClassObject介面上的 QueryInterface,連線到 IWbemObject 介面。

    下列C++程式代碼範例示範如何使用 IWbemObjectAccess 擷取物件的指標,而不是 IWbemClassObject

        // For quick property retrieval, use IWbemObjectAccess.
        IWbemObjectAccess* pAcc = NULL;
        pObj->QueryInterface( IID_IWbemObjectAccess, (void**) &pAcc );
        // This is not required.
        pObj->Release();
    

    IWbemObjectAccess 介面會增加效能,因為您可以取得特定計數器屬性的控制代碼,而且它需要在程式代碼中鎖定並解鎖物件,這是 IWbemClassObject 針對每個屬性存取執行的作業。

  5. 使用呼叫 IWbemObjectAccess::GetPropertyHandle 方法來取得要檢查的屬性句柄。

    類別的所有實例的屬性句柄都相同,這表示針對特定類別的所有實例使用您從特定實例擷取的屬性句柄。 您也可以從類別物件中取得控制代碼,以從實例物件擷取屬性值。

    以下的 C++ 程式碼範例示範如何取得屬性控制代碼。

        // Get a property handle for the VirtualBytes property
        long lVirtualBytesHandle = 0;
        DWORD dwVirtualBytes = 0;
        CIMTYPE variant;
    
        hr = pAcc->GetPropertyHandle(L"VirtualBytes",
             &variant,
             &lVirtualBytesHandle 
        );
        if (FAILED(hr))
        {
           cout << "Could not get property handle. Error code: 0x"
                << hex << hr << endl;
           return hr;
        }
    
  6. 建立執行下列動作的程式設計循環:

    • 使用在上一次呼叫 CoCreateInstance中建立的指標,以呼叫 IWbemRefresher::Refresh 來重新整理物件。

      在此呼叫中,WMI 重新整理器會使用提供者提供的數據來重新整理客戶端物件。

    • 視需要對物件執行任何動作,例如擷取屬性名稱、數據類型或值。

      您可以透過稍早取得的屬性控制代碼來存取該屬性。 由於 Refresh 呼叫,WMI 會每次透過 迴圈重新整理 屬性。

下列C++範例示範如何使用 WMI 高效能 API。

// Get the local locator object
IWbemServices* pNameSpace = NULL;
IWbemLocator* pWbemLocator = NULL;
CIMTYPE variant;
VARIANT VT;

CoCreateInstance( CLSID_WbemLocator, NULL,
    CLSCTX_INPROC_SERVER, IID_IWbemLocator, (void**) &pWbemLocator
);

// Connect to the desired namespace
BSTR bstrNameSpace = SysAllocString( L"\\\\.\\root\\cimv2" );

HRESULT hr = WBEM_S_NO_ERROR;

hr = pWbemLocator->ConnectServer(
     bstrNameSpace,      // Namespace name
     NULL,               // User name
     NULL,               // Password
     NULL,               // Locale
     0L,                 // Security flags
     NULL,               // Authority
     NULL,               // Wbem context
     &pNameSpace         // Namespace
);

if ( SUCCEEDED( hr ) )
{
    // Set namespace security.
    IUnknown* pUnk = NULL;
    pNameSpace->QueryInterface( IID_IUnknown, (void**) &pUnk );

    hr = CoSetProxyBlanket(
         pNameSpace, 
         RPC_C_AUTHN_WINNT, 
         RPC_C_AUTHZ_NONE, 
         NULL, 
         RPC_C_AUTHN_LEVEL_DEFAULT, 
         RPC_C_IMP_LEVEL_IMPERSONATE,
         NULL, 
         EOAC_NONE 
    );
    if (FAILED(hr))
    {
       cout << "Cannot set proxy blanket. Error code: 0x"
            << hex << hr << endl;
       pNameSpace->Release();
       return hr;
    }

    hr = CoSetProxyBlanket(pUnk, 
         RPC_C_AUTHN_WINNT, 
         RPC_C_AUTHZ_NONE, 
         NULL, 
         RPC_C_AUTHN_LEVEL_DEFAULT, 
         RPC_C_IMP_LEVEL_IMPERSONATE,
         NULL, 
         EOAC_NONE 
    );
    if (FAILED(hr))
    {
       cout << "Cannot set proxy blanket. Error code: 0x"
            << hex << hr << endl;
       pUnk->Release();
       return hr;
    }

    // Clean up the IUnknown.
    pUnk->Release();

    IWbemRefresher* pRefresher = NULL;
    IWbemConfigureRefresher* pConfig = NULL;

    // Create a WMI Refresher and get a pointer to the
    // IWbemConfigureRefresher interface.
    CoCreateInstance(CLSID_WbemRefresher, 
                     NULL,
                     CLSCTX_INPROC_SERVER, 
                     IID_IWbemRefresher, 
                     (void**) &pRefresher 
    );
    
    pRefresher->QueryInterface(IID_IWbemConfigureRefresher,
                               (void**) &pConfig );

    IWbemClassObject* pObj = NULL;

    // Add the instance to be refreshed.
    pConfig->AddObjectByPath(
       pNameSpace,
       L"Win32_PerfRawData_PerfProc_Process.Name=\"WINWORD\"",
       0L,
       NULL,
       &pObj,
       NULL 
    );
    if (FAILED(hr))
    {
       cout << "Cannot add object. Error code: 0x"
            << hex << hr << endl;
       pNameSpace->Release();
       
       return hr;
    }

    // For quick property retrieval, use IWbemObjectAccess.
    IWbemObjectAccess* pAcc = NULL;
    pObj->QueryInterface(IID_IWbemObjectAccess, 
                         (void**) &pAcc );

    // This is not required.
    pObj->Release();

    // Get a property handle for the VirtualBytes property.
    long lVirtualBytesHandle = 0;
    DWORD dwVirtualBytes = 0;

    pAcc->GetPropertyHandle(L"VirtualBytes", 
                            &variant, 
                            &lVirtualBytesHandle );

    // Refresh the object ten times and retrieve the value.
    for( int x = 0; x < 10; x++ )
    {
        pRefresher->Refresh( 0L );
        pAcc->ReadDWORD( lVirtualBytesHandle, &dwVirtualBytes );
        printf( "Process is using %lu bytes\n", dwVirtualBytes );
        // Sleep for a second.
        Sleep( 1000 );
    }
    // Clean up all the objects.
    pAcc->Release();
    // Done with these too.
    pConfig->Release();
    pRefresher->Release();
    pNameSpace->Release();
}
SysFreeString( bstrNameSpace );
pWbemLocator->Release();

性能計數器類別

WMI 工作:效能監控