views:

408

answers:

2

I have an app that collects Perfmon counter values through the API exposed in winreg.h - in order to collect Perfmon counter values I must make a call to RegQueryValueExW passing in the id of the Perfmon counter I'm interested in, and in order to obtain that ID I need to query the registry for the list of Perfmon counter names and go through looking for the one I'm interested in

C++ isn't my language of choice, so the following is a shaky example, probably with lots of syntax errors but you get the idea:

DWORD IdProcessIndex = 0;
WCHAR* RawStrings = new WCHAR[ len ];
WCHAR* pCurrent;
DWORD nLenInChars;

// Get the name id of the "ID Process" counter
RegQueryValueExW(HKEY_PERFORMANCE_DATA, COUNTER009, 0, 0, (PBYTE)RawStrings, &len)

pCurrent = (WCHAR*)RawStrings;
while ( (nLenInChars = wcslen(pCurrent)) != 0 && IdProcessIndex == 0 )
{
    WCHAR* pName;
    pName = pCurrent + nLenInChars + 1;

    if ( wcscmp( pName, L"ID Process" ) == 0)
    {
        IdProcessIndex = _wtoi( pCurrent );
    }

    pCurrent = pName + wcslen( pName ) + 1;
}

// Get data for the "ID Process" counter
WCHAR strIdProcessIndex[32];
_itow( nIdProcessIndex, strIdProcessIndex, 10 );

RegQueryValueExW(HKEY_PERFORMANCE_DATA, strIdProcessIndex, NULL, NULL, (PBYTE)pData, &len)

Trouble is that on some machines (ones with the Windows CE dev kit installed) there is a second perfmon counter with the name "ID Process", and so the above finds the ID of the wrong counter.

I cant see any way to differentiate between the two other than the order that they are in - at the moment I think my best bet is to take the first counter that I find with a matching name, is there a better option?

(Its not possible to migrate this to .Net or anything like that)

A: 

I cant see any way to differentiate between the two

Are they giving the same value? If so, why would you care which one you use?

If they're different, can you try both? (e.g., OpenProcess on both IDs)

(Its not possible to migrate this to .Net or anything like that)

How about using the PDH API (e.g., PdhOpenQuery), or the COM interfaces exposed by WMI? You can do both from native C++.

I've never used the performance counters by reading the registry directly, but it may be that there are two "ID Process" counters for some good reason (Like apps under WoW16/64 have separate process IDs?), and an alternative will show the same thing. Do you see two of them in the AdminstrativeTools\Performance MMC panel?

Tim Sylvester
+1  A: 

I realize that this is old, but in case it helps:

  1. Tim is right, parsing the binary data yourself is difficult. Prepare yourself for a world of pain. I'd recommend PDH (encapsulates the registry accesses for you), or if that fails, WMI (though note that WMI is much slower).
  2. You cannot get data for just a performance counter (ID Process, with index 784). You need to get it for the whole object (Process, with index 230).
  3. The IDs for built in objects are guaranteed to be the same on all Windows installations. So if this is the only counter you need, just use 230. :)
Ben Challenor
Thankyou - I hadn't realised that the IDs were gauranteed to be fixed. This makes things a lot simpler!
Kragen
Glad it was useful. Note that this is only true of built in counters, and not counters installed after Windows, such as the SQL Server counters.
Ben Challenor