PDH MSDN samples do not work on Vista RC1 (PDH bugs or MSDN bugs?)

I have been developed a perfomance monitoring solution with Pdh for XP and I have been trying to get it to work on Windows Vista. Essentially the problem involves the logging portion of Pdh in which you create a session, add counters, collect data to the log and then close the log. After that is complete, you open the log for query, add the counters then collect and format the information.

When collecting the information I call PdhCollectQueryData which returns aPDH_NO_DATA error.

In an effort to debug this problem, I created console applications for all the samples on Writing / Reading Performance Data to / from a Log File. Here are the sources (Copied directly from MSDN):

======================= CollectLog.cpp ======================

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <pdh.h>
#include <pdhmsg.h>

void
DisplayCommandLineHelp ()
{
_tprintf (TEXT("\nA valid log name must be specified as the"));
_tprintf (TEXT("\ncommand line argument."));
return;
}

int __cdecl _tmain (int argc, TCHAR **argv)
{

HQUERY hQuery;
HLOG hLog;
PDH_STATUS pdhStatus;
DWORD dwLogType = PDH_LOG_TYPE_CSV;
HCOUNTER hCounter;
TCHAR szCounterPath[PDH_MAX_COUNTER_PATH] =
TEXT("
\\Processor(0)\\% Processor Time");
DWORD dwCount;

if (argc != 2)
{
DisplayCommandLineHelp ();
return -1;
}

// Open a query object.
pdhStatus = PdhOpenQuery (NULL,
0,
&hQuery);

if( pdhStatus != ERROR_SUCCESS )
{
_tprintf(TEXT("PdhOpenQuery failed with %lx\n"), pdhStatus);
return -1;
}

// Add one counter that will provide the data.
pdhStatus = PdhAddCounter (hQuery,
szCounterPath,
0,
&hCounter);

if( pdhStatus != ERROR_SUCCESS )
{
_tprintf(TEXT("PdhAddCounter failed with %lx\n"), pdhStatus);
pdhStatus = PdhCloseQuery (hQuery);
return -1;
}

// Open the log file for write access.
pdhStatus = PdhOpenLog (argv[1],
PDH_LOG_WRITE_ACCESS |
PDH_LOG_CREATE_ALWAYS,
&dwLogType,
hQuery,
0,
NULL,
&hLog);

if( pdhStatus != ERROR_SUCCESS )
{
_tprintf(TEXT("PdhOpenLog failed with %lx\n"), pdhStatus);
pdhStatus = PdhCloseQuery (hQuery);
return -1;
}

// Write 20 records to the log file.
for (dwCount = 0; dwCount <= 20; dwCount++)
{
pdhStatus = PdhUpdateLog (hLog, TEXT("This is a comment."));
// Wait one second between samples for a counter update.
Sleep(1000);
}

// Close the log file.
pdhStatus = PdhCloseLog (hLog, 0);

// Close the query object.
pdhStatus = PdhCloseQuery (hQuery);

return 0;
}

=========================== ConsumeData.cpp =========================

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <pdh.h>
#include <pdhmsg.h>

void
DisplayCommandLineHelp ()
{
_tprintf (TEXT("\nA valid log name must be specified as the"));
_tprintf (TEXT("\ncommand line argument."));
return;
}

int __cdecl _tmain (int argc, TCHAR **argv)
{

HQUERY hQuery;
PDH_STATUS pdhStatus;
DWORD dwFormat = PDH_FMT_DOUBLE;
PDH_FMT_COUNTERVALUE ItemBuffer;
HCOUNTER hCounter;
TCHAR szCounterPath[PDH_MAX_COUNTER_PATH] =
TEXT("\\Processor(0)\\% Processor Time");

if (argc != 2)
{
DisplayCommandLineHelp ();
return -1;
}

// Open a query object.
pdhStatus = PdhOpenQuery (argv[1],
0,
&hQuery);

if( pdhStatus != ERROR_SUCCESS )
{
_tprintf(TEXT("PdhOpenQuery failed with %lx\n"), pdhStatus);
goto cleanup;
}

// Add the counter that created the data in the log file.
pdhStatus = PdhAddCounter (hQuery,
szCounterPath,
0,
&hCounter);
if( pdhStatus != ERROR_SUCCESS )
{
_tprintf(TEXT("PdhAddCounter failed with %lx\n"), pdhStatus);
goto cleanup;
}

// Read a performance data record.
pdhStatus = PdhCollectQueryData(hQuery);
if( pdhStatus != ERROR_SUCCESS )
{
if ( pdhStatus != PDH_NO_MORE_DATA )
{
_tprintf(TEXT("PdhCollectQueryData failed with %lx\n"), pdhStatus);
}
}

while (pdhStatus == ERROR_SUCCESS)
{
// Format the performance data record.
pdhStatus = PdhGetFormattedCounterValue (hCounter,
dwFormat,
(LPDWORD)NULL,
&ItemBuffer);

if (pdhStatus == ERROR_SUCCESS)
{
// Print the performance data record.
_tprintf(TEXT("\nLog Record Value = %4.8f\n"),
ItemBuffer.doubleValue);
}
else
{
_tprintf(TEXT("\nPdhGetFormattedCounterValue failed with %lx.\n"), pdhStatus);
goto cleanup;
}

// Read the next record
pdhStatus = PdhCollectQueryData(hQuery);
if( pdhStatus != ERROR_SUCCESS )
{
if ( pdhStatus != PDH_NO_MORE_DATA )
{
_tprintf(TEXT("PdhCollectQueryData failed with %lx\n"), pdhStatus);
}
}
}

cleanup:
// Close the query.
if (hQuery)
PdhCloseQuery (hQuery);

return pdhStatus;
}

Producing the data works fine, the problem happens when I try to Consume the data, atwhich point I get the response "PdhCollectQueryData failed with 800007D5", which translates to the PDH_NO_DATA error message.

I am using Vista RC 1 Build 5496.

On a seperate note, the MSDN sample about Browsing Performance Counters" has some problems too.

1) It doesn't compile, CHAR szPathBuffer should be TCHAR. szDialogBoxCaption = "Select a counter to monitor" should be TEXT("Select a counter to monitor").

2) It doesn't work, the app returns an error "PdhAddCounter failed with C0000BBD" (note I changed the return value to hex). This error corresponds to PDH_INVALID_ARGUMENT.

All this code works fine on XP, so can I please get a confimation of these problems and/or a fix?


Thanks,

- Tom

[7996 byte] By [Tom-ATI] at [2007-12-25]

Software Development for Windows Vista

Site Classified