How To Retrieve Performance Counter Value Using PDH (287158)
The information in this article applies to:
- Microsoft Win32 Application Programming Interface (API), when used with:
- the operating system: Microsoft Windows NT 4.0
- the operating system: Microsoft Windows 2000
- the operating system: Microsoft Windows XP
This article was previously published under Q287158 SUMMARY
Performance Data Helper (PDH) APIs can be used to collect performance data of various performance counters or instances that are available on the system. This article demonstrates the PDH API calls that are needed to collect performance data for a performance object, counter, and instance name.
MORE INFORMATION
The sample code below has a PDH_COUNTER_PATH_ELEMENTS CPE table that specifies the performance object, counter, and instance names for which the application is collecting the performance data.
#include <windows.h>
#include <pdh.h>
#include <stdio.h>
BOOL WINAPI GetCounterValues(LPTSTR serverName);
void main(int argc, char *argv[])
{
if (argc > 1)
{
// argv[1] - Server Name
GetCounterValues(argv[1]);
}
else
{
// Local System
GetCounterValues(NULL);
}
}
BOOL WINAPI GetCounterValues(LPTSTR serverName)
{
PDH_STATUS s;
HQUERY hQuery;
// Array to specify the performance object, counter and instance for
// which performance data should be collected.
// typedef struct _PDH_COUNTER_PATH_ELEMENTS {
// LPTSTR szMachineName;
// LPTSTR szObjectName;
// LPTSTR szInstanceName;
// LPTSTR szParentInstance;
// DWORD dwInstanceIndex;
// LPTSTR szCounterName;
// } PDH_COUNTER_PATH_ELEMENTS, *PPDH_COUNTER_PATH_ELEMENTS;
// Each element in the array is a PDH_COUNTER_PATH_ELEMENTS structure.
PDH_COUNTER_PATH_ELEMENTS cpe[] =
{
{ NULL, "Memory", NULL, NULL, -1, "Cache Bytes" },
{ NULL, "Memory", NULL, NULL, -1, "Available Bytes" },
{ NULL, "Processor", "_Total", NULL, -1, "% Processor Time" }
};
HCOUNTER hCounter[sizeof(cpe)/sizeof(cpe[0])];
char szFullPath[MAX_PATH];
DWORD cbPathSize;
int i, j;
BOOL ret = FALSE;
PDH_FMT_COUNTERVALUE counterValue;
// Only do this setup once.
if ((s = PdhOpenQuery(NULL, 0, &hQuery)) != ERROR_SUCCESS)
{
fprintf(stderr, "POQ failed %08x\n", s);
return ret;
}
for (i = 0; i < sizeof(hCounter)/sizeof(hCounter[0]); i++)
{
cbPathSize = sizeof(szFullPath);
cpe[i].szMachineName = serverName;
if ((s = PdhMakeCounterPath(&cpe[i],
szFullPath, &cbPathSize, 0)) != ERROR_SUCCESS)
{
fprintf(stderr,"MCP failed %08x\n", s);
return ret;
}
if (cpe[i].szInstanceName)
{
printf("Adding [%s\\%s\\%s]\n",
cpe[i].szObjectName,
cpe[i].szCounterName,
cpe[i].szInstanceName);
}
else
printf("Adding [%s\\%s]\n",
cpe[i].szObjectName,
cpe[i].szCounterName);
if ((s = PdhAddCounter(hQuery, szFullPath, 0, &hCounter[i]))
!= ERROR_SUCCESS)
{
fprintf(stderr, "PAC failed %08x\n", s);
return ret;
}
}
for (i = 0; i < 20; i++)
{
Sleep(100);
// Collect data as often as you need to.
if ((s = PdhCollectQueryData(hQuery)) != ERROR_SUCCESS)
{
fprintf(stderr, "PCQD failed %08x\n", s);
return ret;
}
if (i == 0) continue;
// Extract the calculated performance counter value for each counter or
// instance.
for (j = 0; j < sizeof(hCounter)/sizeof(hCounter[0]); j++)
{
if ((s = PdhGetFormattedCounterValue(hCounter[j], PDH_FMT_DOUBLE,
NULL, &counterValue)) != ERROR_SUCCESS)
{
fprintf(stderr, "PGFCV failed %08x\n", s);
continue;
}
if (cpe[j].szInstanceName)
{
printf("%s\\%s\\%s\t\t : [%3.3f]\n",
cpe[j].szObjectName,
cpe[j].szCounterName,
cpe[j].szInstanceName,
counterValue.doubleValue);
}
else
printf("%s\\%s\t\t : [%3.3f]\n",
cpe[j].szObjectName,
cpe[j].szCounterName,
counterValue.doubleValue);
}
}
// Remove all the counters from the query.
for (i = 0; i < sizeof(hCounter)/sizeof(hCounter[0]); i++)
{
PdhRemoveCounter(hCounter[i]);
}
// Only do this cleanup once.
PdhCloseQuery(hQuery);
return TRUE;
}
REFERENCES
PDH APIs are implemented in the Pdh.dll file that ships with the Microsoft Windows 2000 and Microsoft Windows XP operating system. For the Microsoft Windows NT 4.0 operating system, you can download a separate redistributable Pdh.dll version.
For additional information on how to obtain the redistributable version of Pdh.dll for Windows NT 4.0, click the article number below
to view the article in the Microsoft Knowledge Base:
284996 FILE: Latest Redistributable PDH.dll Available for Windows NT 4.0
For additional information on the PDH APIs, see the "Performance Monitoring" topic in the "Base Services" section of the MSDN Library.
Modification Type: | Minor | Last Reviewed: | 3/22/2005 |
---|
Keywords: | kbAPI kbhowto kbKernBase kbPerfMon KB287158 |
---|
|