Udostępnij za pośrednictwem


Uzyskiwanie dostępu do wstępnie zainstalowanych klas wydajności usługi WMI

Repozytorium WMI zawiera wstępnie zainstalowane klasy wydajności dla wszystkich obiektów biblioteki wydajności. Na przykład wystąpienia klasy wydajności danych pierwotnych Win32_PerfRawData_PerfProc_Process reprezentują procesy. Ten obiekt wydajności jest widoczny w monitorze systemu jako obiekt Procesu.

Właściwość PageFaultsPerSec obiektu Win32_PerfRawData_PerfProc_Process reprezentuje miernik błędów strony na sekundę dla procesu. Klasy Win32_PerfFormattedData zawierają obliczone wartości danych wyświetlane w monitorze systemu (Perfmon.exe). Wartość właściwości PageFaultsPerSecWin32_PerfFormattedData_PerfProc_Process jest taka sama, jak kiedy pojawia się w Monitorze systemu.

Użyj interfejsu API COM dla usługi WMI lub interfejsu API skryptów dla usługi WMI, aby uzyskać dostęp do danych wydajności za pośrednictwem klas liczników wydajności . W obu przypadkach wymagany jest obiekt odświeżania do uzyskania każdej próbki danych. Aby uzyskać więcej informacji i przykłady kodu skryptu dotyczące używania odświeżaczy i uzyskiwania dostępu do klas wydajności, zobacz zadania WMI: Monitorowanie wydajności. Aby uzyskać więcej informacji, zobacz Uzyskiwanie dostępu do danych wydajności w skryptach.

Uzyskiwanie dostępu do danych wydajności z języka C++

Poniższy przykład kodu C++ używa dostawcy licznika wydajności do uzyskiwania dostępu do wstępnie zdefiniowanych klas o wysokiej wydajności. Tworzy obiekt odświeżania i dodaje obiekt do obiektu odświeżania. Obiekt jest instancją Win32_PerfRawData_PerfProc_Process, która monitoruje wydajność określonego procesu. Kod odczytuje tylko jedną właściwość licznika w obiekcie procesu, właściwość VirtualBytes. Kod wymaga następujących odwołań i instrukcji #include w celu poprawnego skompilowania.

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

Poniższa procedura przedstawia sposób uzyskiwania dostępu do danych od dostawcy o wysokiej wydajności w języku C++.

Aby uzyskać dostęp do danych od dostawcy o wysokiej wydajności w języku C++

  1. Nawiąż połączenie z przestrzenią nazw WMI i ustaw zabezpieczenia WMI za pomocą wywołania IWbemLocator::ConnectServer oraz CoSetProxyBlanket.

    Ten krok jest standardowym krokiem tworzenia dowolnej aplikacji klienckiej usługi WMI. Aby uzyskać więcej informacji, zobacz Creating a WMI Application Using C++.

  2. Utwórz obiekt do odświeżania przy użyciu CoCreateInstance z CLSID_WbemRefresher. Zażądaj interfejsu IWbemConfigureRefresher za pomocą metody QueryInterface. Zażądaj interfejsu IWbemRefresher za pomocą metody QueryInterface.

    Interfejs IWbemRefresher jest głównym interfejsem obiektu WMI Refresher.

    Poniższy przykład kodu C++ pokazuje, jak pobrać 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. Dodaj obiekt do modułu odświeżania za pomocą wywołania metody IWbemConfigureRefresher::AddObjectByPath.

    Po dodaniu obiektu do modułu odświeżania usługa WMI odświeża obiekt za każdym razem, gdy wywołujesz metodę IWbemRefresher::Refresh. Dodany obiekt wyznacza dostawcę w kwalifikatorach klas.

    Poniższy przykład kodu C++ pokazuje, jak wywołać 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. Aby skonfigurować szybszy dostęp do obiektu, połącz się z interfejsem IWbemObjectAccess za pomocą QueryInterface w interfejsie IWbemClassObject.

    Poniższy przykład kodu C++ pokazuje, jak pobrać wskaźnik do obiektu przy użyciu IWbemObjectAccess zamiast IWbemClassObject.

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

    Interfejs IWbemObjectAccess zwiększa wydajność, ponieważ można uzyskać dojścia do określonych właściwości licznika i wymaga zablokowania i odblokowania obiektu w kodzie, czyli operacji, która IWbemClassObject wykonuje dla każdego dostępu do właściwości.

  5. Uzyskaj dojścia właściwości do zbadania przy użyciu wywołań do metody IWbemObjectAccess::GetPropertyHandle.

    Uchwyty właściwości są takie same dla wszystkich wystąpień klasy, co oznacza, że można używać uchwytu właściwości pobranego z konkretnego wystąpienia dla wszystkich wystąpień danej klasy. Można również uzyskać uchwyt z obiektu klasy, aby uzyskać wartości właściwości z instancji obiektu.

    W poniższym przykładzie kodu języka C++ pokazano, jak pobrać uchwyt właściwości.

        // 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. Utwórz pętlę programowania, która wykonuje następujące akcje:

    • Odśwież obiekt poprzez wywołanie IWbemRefresher::Refresh przy użyciu wskaźnika utworzonego podczas poprzedniego wywołania CoCreateInstance.

      W tym wywołaniu usługa WMI odświeża obiekt klienta za pomocą danych dostarczanych przez dostawcę.

    • Wykonaj dowolną akcję zgodnie z potrzebami w obiekcie, na przykład pobieranie nazwy właściwości, typu danych lub wartości.

      Dostęp do właściwości można uzyskać za pomocą uzyskanego wcześniej uchwytu właściwości. Ze względu na wywołanie Refresh, usługa WMI odświeża właściwość przy każdym przejściu przez pętlę.

W poniższym przykładzie języka C++ pokazano, jak używać interfejsu API wysokiej wydajności usługi 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();

klasy liczników wydajności

Zadania WMI: Monitorowanie wydajności