Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Interfejs API wysokiej wydajności usługi WMI to seria interfejsów, które uzyskują dane z klas liczników wydajności . Te interfejsy wymagają użycia obiektu odświeżania w celu zwiększenia częstotliwości próbkowania. Aby uzyskać więcej informacji na temat używania obiektu odświeżania w skryptach, zobacz Uzyskiwanie dostępu do danych wydajności w skrypcie i Zadania usługi WMI: Monitorowanie wydajności.
W tym temacie omówiono następujące sekcje:
Odświeżanie danych wydajności
Obiekt odświeżania zwiększa wydajność dostawcy danych i klienta przez pobieranie danych bez przekraczania granic procesów. Jeśli klient i serwer znajdują się na tym samym komputerze, moduł odświeżający ładuje dostawcę o wysokiej wydajności do klienta jako proces wewnętrzny i kopiuje dane bezpośrednio z obiektów dostawcy do obiektów klienta. Jeśli klient i serwer znajdują się na różnych komputerach, odświeżanie zwiększa wydajność przez buforowanie obiektów na komputerze zdalnym i przesyłanie minimalnych zestawów danych do klienta.
Przypomnienie także:
Automatycznie ponownie łączy klienta z zdalną usługą WMI po wystąpieniu błędu sieci lub ponownego uruchomienia komputera zdalnego.
Domyślnie odświeżanie próbuje ponownie nawiązać połączenie aplikacji z odpowiednim dostawcą o wysokiej wydajności, w przypadku, gdy połączenie zdalne między dwoma komputerami zakończy się niepowodzeniem. Aby zapobiec ponownemu połączeniu, przekaż flagę WBEM_FLAG_REFRESH_NO_AUTO_RECONNECT w wywołaniu metody Refresh. Klienci skryptów muszą ustawić właściwość SWbemRefresher.AutoReconnect na FALSE.
Ładuje wiele obiektów i modułów wyliczających udostępnianych przez tych samych lub różnych dostawców.
Umożliwia dodawanie wielu obiektów, wyliczników lub obu do odświeżacza.
Wylicza obiekty.
Podobnie jak inni dostawcy, dostawca o wysokiej wydajności może wyliczać obiekty.
Po napisaniu wydajnego klienta możesz zechcieć poprawić czas odpowiedzi. Ponieważ interfejs IWbemObjectAccess jest zoptymalizowany pod kątem szybkości, nie jest on wewnętrznie bezpieczny wątkowo. W związku z tym podczas operacji odświeżania nie należy uzyskiwać dostępu do obiektu lub wyliczenia z możliwością odświeżania. Aby chronić obiekty między wątkami podczas wywołań metody IWbemObjectAccess, użyj metod IWbemObjectAccess::Lock i Unlock. Aby zwiększyć wydajność, zsynchronizuj wątki, aby nie trzeba było blokować poszczególnych wątków. Zmniejszenie liczby wątków i synchronizowanie grup obiektów na potrzeby operacji odświeżania zapewnia najlepszą ogólną wydajność.
Dodawanie enumeratorów do odświeżacza WMI
Zarówno liczba wystąpień, jak i dane w każdym wystąpieniu są odświeżane przez dodanie enumeratora do odświeżacza, co sprawia, że każde wywołanie metody IWbemRefresher::Odśwież skutkuje pełnym wyliczeniem.
Poniższy przykład kodu C++ 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 dodawania wylicznika do odświeżacza.
Aby dodać wylicznik do odświeżacza
Wywołaj metodę IWbemConfigureRefresher::AddEnum, używając ścieżki do obiektu możliwego do odświeżenia i interfejsu IWbemServices.
Moduł odświeżania zwraca wskaźnik do interfejsu IWbemHiPerfEnum. Aby uzyskać dostęp do obiektów w wyliczeniu, możesz użyć interfejsu IWbemHiPerfEnum.
IWbemHiPerfEnum* pEnum = NULL; long lID; IWbemConfigureRefresher* pConfig; IWbemServices* pNameSpace; // Add an enumerator to the refresher. if (FAILED (hr = pConfig->AddEnum( pNameSpace, L"Win32_PerfRawData_PerfProc_Process", 0, NULL, &pEnum, &lID))) { goto CLEANUP; } pConfig->Release(); pConfig = NULL;Utwórz pętlę wykonującą następujące akcje:
Odświeża obiekt za pomocą wywołania metody IWbemRefresher::Refresh.
Udostępnia tablicę wskaźników interfejsu IWbemObjectAccess do metody IWbemHiPerfEnum::GetObjects.
Uzyskuje dostęp do właściwości modułu wyliczającego przy użyciu metod IWbemObjectAccess przekazywanych do GetObjects.
Do każdego wystąpienia IWbemObjectAccess można przekazać uchwyt właściwości w celu pobrania odświeżonej wartości. Klient musi wywołać Release, aby zwolnić wskaźniki IWbemObjectAccess zwrócone przez GetObjects.
Przykład
Poniższy przykład kodu C++ wylicza klasę o wysokiej wydajności, gdzie klient pobiera uchwyt właściwości z pierwszego obiektu i ponownie używa uchwytu dla pozostałej części operacji odświeżania. Każde wywołanie metody Refresh aktualizuje liczbę wystąpień i danych wystąpienia.
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <Wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
int __cdecl wmain(int argc, wchar_t* argv[])
{
// To add error checking,
// check returned HRESULT below where collected.
HRESULT hr = S_OK;
IWbemRefresher *pRefresher = NULL;
IWbemConfigureRefresher *pConfig = NULL;
IWbemHiPerfEnum *pEnum = NULL;
IWbemServices *pNameSpace = NULL;
IWbemLocator *pWbemLocator = NULL;
IWbemObjectAccess **apEnumAccess = NULL;
BSTR bstrNameSpace = NULL;
long lID = 0;
long lVirtualBytesHandle = 0;
long lIDProcessHandle = 0;
DWORD dwVirtualBytes = 0;
DWORD dwProcessId = 0;
DWORD dwNumObjects = 0;
DWORD dwNumReturned = 0;
DWORD dwIDProcess = 0;
DWORD i=0;
int x=0;
if (FAILED (hr = CoInitializeEx(NULL,COINIT_MULTITHREADED)))
{
goto CLEANUP;
}
if (FAILED (hr = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_NONE,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, 0)))
{
goto CLEANUP;
}
if (FAILED (hr = CoCreateInstance(
CLSID_WbemLocator,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(void**) &pWbemLocator)))
{
goto CLEANUP;
}
// Connect to the desired namespace.
bstrNameSpace = SysAllocString(L"\\\\.\\root\\cimv2");
if (NULL == bstrNameSpace)
{
hr = E_OUTOFMEMORY;
goto CLEANUP;
}
if (FAILED (hr = pWbemLocator->ConnectServer(
bstrNameSpace,
NULL, // User name
NULL, // Password
NULL, // Locale
0L, // Security flags
NULL, // Authority
NULL, // Wbem context
&pNameSpace)))
{
goto CLEANUP;
}
pWbemLocator->Release();
pWbemLocator=NULL;
SysFreeString(bstrNameSpace);
bstrNameSpace = NULL;
if (FAILED (hr = CoCreateInstance(
CLSID_WbemRefresher,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWbemRefresher,
(void**) &pRefresher)))
{
goto CLEANUP;
}
if (FAILED (hr = pRefresher->QueryInterface(
IID_IWbemConfigureRefresher,
(void **)&pConfig)))
{
goto CLEANUP;
}
// Add an enumerator to the refresher.
if (FAILED (hr = pConfig->AddEnum(
pNameSpace,
L"Win32_PerfRawData_PerfProc_Process",
0,
NULL,
&pEnum,
&lID)))
{
goto CLEANUP;
}
pConfig->Release();
pConfig = NULL;
// Get a property handle for the VirtualBytes property.
// Refresh the object ten times and retrieve the value.
for(x = 0; x < 10; x++)
{
dwNumReturned = 0;
dwIDProcess = 0;
dwNumObjects = 0;
if (FAILED (hr =pRefresher->Refresh(0L)))
{
goto CLEANUP;
}
hr = pEnum->GetObjects(0L,
dwNumObjects,
apEnumAccess,
&dwNumReturned);
// If the buffer was not big enough,
// allocate a bigger buffer and retry.
if (hr == WBEM_E_BUFFER_TOO_SMALL
&& dwNumReturned > dwNumObjects)
{
apEnumAccess = new IWbemObjectAccess*[dwNumReturned];
if (NULL == apEnumAccess)
{
hr = E_OUTOFMEMORY;
goto CLEANUP;
}
SecureZeroMemory(apEnumAccess,
dwNumReturned*sizeof(IWbemObjectAccess*));
dwNumObjects = dwNumReturned;
if (FAILED (hr = pEnum->GetObjects(0L,
dwNumObjects,
apEnumAccess,
&dwNumReturned)))
{
goto CLEANUP;
}
}
else
{
if (hr == WBEM_S_NO_ERROR)
{
hr = WBEM_E_NOT_FOUND;
goto CLEANUP;
}
}
// First time through, get the handles.
if (0 == x)
{
CIMTYPE VirtualBytesType;
CIMTYPE ProcessHandleType;
if (FAILED (hr = apEnumAccess[0]->GetPropertyHandle(
L"VirtualBytes",
&VirtualBytesType,
&lVirtualBytesHandle)))
{
goto CLEANUP;
}
if (FAILED (hr = apEnumAccess[0]->GetPropertyHandle(
L"IDProcess",
&ProcessHandleType,
&lIDProcessHandle)))
{
goto CLEANUP;
}
}
for (i = 0; i < dwNumReturned; i++)
{
if (FAILED (hr = apEnumAccess[i]->ReadDWORD(
lVirtualBytesHandle,
&dwVirtualBytes)))
{
goto CLEANUP;
}
if (FAILED (hr = apEnumAccess[i]->ReadDWORD(
lIDProcessHandle,
&dwIDProcess)))
{
goto CLEANUP;
}
wprintf(L"Process ID %lu is using %lu bytes\n",
dwIDProcess, dwVirtualBytes);
// Done with the object
apEnumAccess[i]->Release();
apEnumAccess[i] = NULL;
}
if (NULL != apEnumAccess)
{
delete [] apEnumAccess;
apEnumAccess = NULL;
}
// Sleep for a second.
Sleep(1000);
}
// exit loop here
CLEANUP:
if (NULL != bstrNameSpace)
{
SysFreeString(bstrNameSpace);
}
if (NULL != apEnumAccess)
{
for (i = 0; i < dwNumReturned; i++)
{
if (apEnumAccess[i] != NULL)
{
apEnumAccess[i]->Release();
apEnumAccess[i] = NULL;
}
}
delete [] apEnumAccess;
}
if (NULL != pWbemLocator)
{
pWbemLocator->Release();
}
if (NULL != pNameSpace)
{
pNameSpace->Release();
}
if (NULL != pEnum)
{
pEnum->Release();
}
if (NULL != pConfig)
{
pConfig->Release();
}
if (NULL != pRefresher)
{
pRefresher->Release();
}
CoUninitialize();
if (FAILED (hr))
{
wprintf (L"Error status=%08x\n",hr);
}
return 1;
}
Tematy pokrewne
-
kwalifikatory właściwości dla sformatowanych klas liczników wydajności