Доступ к предварительно установленным классам производительности WMI
Репозиторий WMI содержит предварительно установленные классы производительности для всех объектов библиотеки производительности. Например, экземпляры класса производительности необработанных данных Win32_PerfRawData_PerfProc_Process представляют процессы. Этот объект производительности отображается в System Monitor как объект Process.
Свойство PageFaultsPerSec объекта Win32_PerfRawData_PerfProc_Process представляет счетчик числа страничных отказов в секунду для процесса. Классы Win32_PerfFormattedData содержат вычисляемые значения данных, отображаемые в System Monitor (Perfmon.exe). Значение свойства PageFaultsPerSecWin32_PerfFormattedData_PerfProc_Process такое же, как и при отображении в Системном мониторе.
Используйте COM-API для WMI или API скриптов для WMI для доступа к данным о производительности через классы счетчиков производительности . В обоих случаях для получения каждого примера данных требуется объект обновления . Дополнительные сведения и примеры кода скрипта для использования освежителей и доступа к классам производительности, см. в задачах 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 и задайте безопасность WMI с помощью вызова IWbemLocator::ConnectServer и CoSetProxyBlanket.
Этот шаг является стандартным шагом для создания любого клиентского приложения WMI. Дополнительные сведения см. в статье Создание приложения WMI с помощьюC++.
Создайте объект обновления с помощью CoCreateInstance с CLSID_WbemRefresher. Запросите интерфейс IWbemConfigureRefresher через метод QueryInterface. Запросите интерфейс IWbemRefresher через метод QueryInterface.
Интерфейс 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.
При добавлении объекта в средство обновления WMI обновляет объект при вызове метода IWbemRefresher::Refresh. Добавляемый объект определяет поставщика в его классовых квалификаторах.
В следующем примере кода 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; }
Чтобы ускорить доступ к объекту, подключитесь к интерфейсу IWbemObjectAccess через QueryInterface на интерфейсе IWbemClassObject.
В следующем примере кода 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; }
Создайте цикл программирования, выполняющий следующие действия:
Обновите объект с помощью вызова IWbemRefresher::Refresh с помощью указателя, созданного в предыдущем вызове CoCreateInstance.
В этом вызове средство обновления WMI обновляет клиентский объект с помощью данных, предоставляемых поставщиком.
Выполните при необходимости любое действие с объектом, например, получение имени свойства, типа данных или значения.
Вы можете получить доступ к свойству с помощью дескриптора свойства, полученного ранее. Из-за вызова обновления WMI обновляет свойство каждый раз через цикл.
В следующем примере C++ показано, как использовать ВЫСОКОпроизводительный API WMI.
// 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();
Связанные разделы