Microsoft KB Archive/287158

{|
 * width="100%"|

HOWTO: Retrieve Performance Counter Value Using PDH

 * }

Q287158

-

The information in this article applies to:


 * Microsoft Win32 Application Programming Interface (API), included with:
 * the operating system: Microsoft Windows 2000
 * the operating system: Microsoft Windows NT 4.0

-

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 
 * 1) include 
 * 2) include 

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, &quot;Memory&quot;, NULL, NULL, -1, &quot;Cache Bytes&quot; }, { NULL, &quot;Memory&quot;, NULL, NULL, -1, &quot;Available Bytes&quot; }, { NULL, &quot;Processor&quot;, &quot;_Total&quot;, NULL, -1, &quot;% Processor Time&quot; } };

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, &quot;POQ failed %08x\n&quot;, 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,&quot;MCP failed %08x\n&quot;, s); return ret; }

if (cpe[i].szInstanceName) {           printf(&quot;Adding [%s\\%s\\%s]\n&quot;,                    cpe[i].szObjectName,                    cpe[i].szCounterName,                    cpe[i].szInstanceName); }       else printf(&quot;Adding [%s\\%s]\n&quot;,                   cpe[i].szObjectName,                    cpe[i].szCounterName);

if ((s = PdhAddCounter(hQuery, szFullPath, 0, &hCounter[i]))           != ERROR_SUCCESS) {           fprintf(stderr, &quot;PAC failed %08x\n&quot;, 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, &quot;PCQD failed %08x\n&quot;, 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, &quot;PGFCV failed %08x\n&quot;, s); continue; }           if (cpe[j].szInstanceName) {               printf(&quot;%s\\%s\\%s\t\t : [%3.3f]\n&quot;,                    cpe[j].szObjectName,                    cpe[j].szCounterName,                    cpe[j].szInstanceName,                    counterValue.doubleValue); }           else printf(&quot;%s\\%s\t\t : [%3.3f]\n&quot;,                   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; }