Mengakses Kelas Performa WMI yang Telah Diinstal Sebelumnya

Repositori WMI berisi kelas performa yang telah diinstal sebelumnya untuk semua objek pustaka performa. Misalnya, instans kelas performa data mentah Win32_PerfRawData_PerfProc_Process mewakili proses. Objek performa ini terlihat di Monitor Sistem sebagai objek Proses.

Properti PageFaultsPerSecdari Win32_PerfRawData_PerfProc_Process mewakili penghitung kinerja Kesalahan Halaman per detik untuk proses tersebut. Kelas Win32_PerfFormattedData berisi nilai data terhitung yang ditampilkan di Monitor Sistem (Perfmon.exe). Nilai properti PageFaultsPerSecdari Win32_PerfFormattedData_PerfProc_Process sama seperti saat muncul di Monitor Sistem.

Gunakan COM API untuk WMI atau Scripting API untuk WMI untuk mengakses data performa melalui Kelas Penghitung Kinerja. Dalam kedua kasus, objek penyegaran diperlukan untuk mendapatkan setiap sampel data. Untuk informasi selengkapnya dan contoh kode skrip untuk menggunakan penyegar dan mengakses kelas performa, lihat Tugas WMI: Pemantauan Performa. Untuk informasi selengkapnya, lihat Mengakses Data Performa dalam Skrip.

Mengakses Data Performa dari C++

Contoh kode C++ berikut menggunakan penyedia Penghitung Kinerja untuk mengakses kelas berkinerja tinggi yang telah ditentukan sebelumnya. Ini membuat objek penyegar dan menambahkan objek ke penyegaran. Objek adalah instans Win32_PerfRawData_PerfProc_Process yang memantau performa proses tertentu. Kode hanya membaca satu properti penghitung dalam objek proses, properti VirtualBytes . Kode memerlukan referensi berikut dan pernyataan #include untuk dikompilasi dengan benar.

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

Prosedur berikut menunjukkan cara mengakses data dari penyedia berkinerja tinggi di C++.

Untuk mengakses data dari penyedia berkinerja tinggi di C++

  1. Buat koneksi ke namespace WMI, dan atur keamanan WMI dengan menggunakan panggilan ke IWbemLocator::ConnectServer dan CoSetProxyBlanket.

    Langkah ini adalah langkah standar untuk membuat aplikasi klien WMI apa pun. Untuk informasi selengkapnya, lihat Membuat Aplikasi WMI Menggunakan C++.

  2. Buat objek penyegaran dengan menggunakan CoCreateInstance dengan CLSID_WbemRefresher. Minta antarmuka IWbemConfigureRefresher melalui metode QueryInterface . Minta antarmuka IWbemRefresher melalui metode QueryInterface .

    Antarmuka IWbemRefresher adalah antarmuka utama untuk objek WMI Refresher .

    Contoh kode C++ berikut menunjukkan cara mengambil 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. Tambahkan objek ke penyegaran melalui panggilan ke metode IWbemConfigureRefresher::AddObjectByPath .

    Saat Anda menambahkan objek ke penyegaran, WMI merefresh objek setiap kali Anda memanggil metode IWbemRefresher::Refresh . Objek yang Anda tambahkan menunjuk penyedia dalam kualifikasi kelasnya.

    Contoh kode C++ berikut menunjukkan cara memanggil 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. Untuk menyiapkan akses yang lebih cepat ke objek, sambungkan ke antarmuka IWbemObjectAccess melalui QueryInterface pada antarmuka IWbemClassObject .

    Contoh kode C++ berikut menunjukkan cara mengambil pointer ke objek menggunakan IWbemObjectAccess alih-alih IWbemClassObject.

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

    Antarmuka IWbemObjectAccess meningkatkan performa karena Anda bisa menangani properti penghitung tertentu, dan mengharuskan Anda mengunci dan membuka kunci objek dalam kode Anda, yang merupakan operasi yang dilakukan IWbemClassObject untuk setiap akses properti.

  5. Dapatkan handel properti untuk diperiksa dengan menggunakan panggilan ke metode IWbemObjectAccess::GetPropertyHandle .

    Handel properti sama untuk semua instans kelas, yang berarti menggunakan handel properti yang Anda ambil dari instans tertentu untuk semua instans kelas tertentu. Anda juga dapat memperoleh handel dari objek kelas untuk mengambil nilai properti dari objek instans.

    Contoh kode C++ berikut menunjukkan cara mengambil handel properti.

        // 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. Buat perulangan pemrograman yang melakukan tindakan berikut:

    • Refresh objek dengan panggilan ke IWbemRefresher::Refresh dengan menggunakan penunjuk yang dibuat di panggilan sebelumnya ke CoCreateInstance.

      Dalam panggilan ini, Penyegar WMI me-refresh objek klien dengan menggunakan data yang disediakan penyedia.

    • Lakukan tindakan apa pun seperlunya pada objek, seperti mengambil nama properti, jenis data, atau nilai.

      Anda dapat mengakses properti melalui handel properti yang diperoleh sebelumnya. Karena panggilan Refresh , WMI me-refresh properti setiap kali melalui perulangan.

Contoh C++ berikut menunjukkan cara menggunakan API berkinerja tinggi 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();

Kelas Penghitung Kinerja

Tugas WMI: Pemantauan Performa