存取 WMI 預先安裝效能類別
WMI 存放庫包含所有效能程式庫物件的預先安裝效能類別。 例如,原始資料效能類別的實例 Win32_PerfRawData_PerfProc_Process 表示進程。 此效能物件會顯示在 System Monitor 中做為 Process 物件。
Win32_PerfRawData_PerfProc_Process的 PageFaultsPerSec屬性代表進程的每秒分頁錯誤效能計數器。 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++ 中的高效能提供者存取資料
建立與 WMI 命名空間的連線,並使用 呼叫 IWbemLocator::ConnectServer 和 CoSetProxyBlanket來設定 WMI 安全性。
此步驟是建立任何 WMI 用戶端應用程式的標準步驟。 如需詳細資訊,請參閱 使用 C++ 建立 WMI 應用程式。
使用 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 );
透過呼叫 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; }
若要設定更快速地存取物件,請透過IWbemClassObject介面上的QueryInterface連接到IWbemObjectAccess介面。
下列 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針對每個屬性存取所執行的作業。
使用 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; }
建立執行下列動作的程式設計迴圈:
使用上一次呼叫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();
相關主題