Jump to content

Performance Counters in Windows - Measure Process, CPU, Network, Disk Usage


Ascend4nt
 Share

Recommended Posts

PDH Performance Counters

Measure Process, CPU, Network, Process, Disk (etc) Usage

Posted Image

(note that the above dialog appears differently on Vista+)

New ObjectBase interface!!

*x64 and Localization Issues have been resolved!*

*Download and License agreement are at the bottom of this post!

About The Project:

Performance Counters gather all kind of performance data about the PC and the Network using the standard PDH.DLL module (standard since Windows 2000).

Among the performance data you can collect and monitor are:

  • Processor Stats (including total usage)
  • Process (programs) Stats (including CPU usage)
  • Disk Stats (speed/access)
  • TCP, UDP, IP Connection Counts, Speed/Error Stats
  • Network Stats
  • ..and so on
Note that one example is a WIP. 'TaskManager' mockup UDF, I'm looking at you.

You can jump right in, download the two AutoIT files (below) and run one of the following to see what the PDH Performance Counters project can get you:

  • TestPDH_PerformanceCounters - this is where you should start! It allows you to visually experiment with most all of the Counters available on your PC and Network.

    NOTES:

    - Currently the 'Refresh' rate is set to 1/2 second - this can be changed by altering the Adlib() function frequency

    - New Counters that come into existence during monitoring will *not* be added to the list (this would be a function I've yet to add)

    - Counters that become invalid are simply given a prefix of '[Dead Counter Handle]:'

Posted Image

  • TestPDH_ProcessLoop - this basically repeatedly shows an extended Process-information list for all processes. NOTE: You must hit 'ESC' to exit the loop

Posted Image

  • TestPDH_TaskManager - this gathers and displays most everything you'd see in the Process and Performance sections of Task Manager.

    NOTES:

    - The screen does NOT update, and the UDF is a MESS. This is due to a number of reasons - the biggest one being laziness on my behalf. Plus I need to figure out how best to manage ListView changes.

    - TWO fields need Windows XP+ to display correctly (or a version of psapi.dll that supports 'GetPerformanceInfo'): Commit Charge (Peak) and System Cache

Posted Image

  • TestPDH_ProcessGetRelatives - this shows how the PDH Performance Counters can be used to get 'parent' and 'children' process information. There are more practical means of getting this info of course (a few you'll see in my 'Process Functions' module, but hey - its just yet another example of what can be done.
  • TestPDH_ObjectTests - this is more for reading/understanding the code than anything. It is there to show how the new 'ObjectBase' Interface works to make coding Performance Counters *much* easier.
  • Multipile extra 'TestPDH*' examples
At its most basic, interacting with Performance Counters is as such:

  • _PDH_Init() must be called to Initialize the PDH Performance Counters. This is a *MUST*.

    This does the following:

    - Verifies Performance Counters aren't disabled in the Registry. If they *ARE*, it tries to enable them. Note this may require Admin authorization as the keys are located in the HKLM branch

    - Loads the PDH.DLL, which in turn generates a file in the @TempDir named something like 'Perflib_Perfdata_xxx.dat' (around ~16KB)

  • _PDH_GetNewQueryHandle() needs to be called to get a PDH Query Handle. This handle is used to add Counters to, and everytime this is updated, all Counters attached will be updated.
  • _PDH_AddCounter() needs to be called to add Counters to the PDH Query Handle (for as many counters as need to be added). These can be in Localized ("\\PCNAME\Object(Instance)\Counter") or non-localized format (":\##\##\(Instance)\PCNAME"), and can contain a Wildcard ("*") in place of one of the parts of the path (Object, Instance, or Counter)
  • _PDH_CollectQueryData() should be called, followed by a sleep for what I term a 'baseline-sleep' model - allows counters to initialize
  • _PDH_UpdateCounter(), _PDH_UpdateCounters(), or _PDH_UpdateWildcardCounter() should be called to get the Counter values. Call this at regular intervals to get updated Performance Information.
  • _PDH_FreeQueryHandle() should be called for each Query handle obtained. This automatically releases the Counters that were attached, as well.
  • _PDH_UnInit() must be called to cleanup before exiting.

The brand new ObjectBase Interface removes some of the difficulty in interacting with Performance Counters, and works like this:

  • _PDH_Init() as usual
  • _PDH_ObjectBaseCreate(), _PDH_ProcessObjectCreate(), or _PDH_ProcessAlInit() must be called to create a special 'ObjectBase' Counter Array.
  • _PDH_ObjectBaseAddCounters(), _PDH_ProcessObjectAddCounters(), or _PDH_ProcessAllAddCounters() must be called to add Counters to the ObjectBase. These can be passed by index # or Local string form in a multiple-Counter string, and can optionally be added on Object Creation (except for ProcessObjects).
  • _PDH_ObjectBaseCollectQueryData(), _PDH_ProcessObjectCollectQueryData(), or _PDH_ProcessAllCollectQueryData() should be called, followed by a sleep for what I term a 'baseline-sleep' model - allows counters to initialize
  • _PDH_ObjectBaseUpdateCounters(), _PDH_ProcessObjectUpdateCounters(), or _PDH_ProcessAllUpdateCounters() must be called to update the ObjectBase Counters and retrieve current performance data. Call these at regular intervals to get updated Performance Information.
  • _PDH_ObjectBaseDestroy(), _PDH_ProcessObjectDestroy(), or _PDH_ProcessAllUnInit() must be called to Destroy the 'ObjectBase' array (and free its Query handle)
  • _PDH_UnInit() as usual

Examples of the new ObjectBase interface:

% CPU Usage of a Process

% CPU Usage of Multiple Instances of a Process (+monitoring and adjustment based on new/dead Instances)

Other Examples:

Waiting for Hard Disk activity to Idle for 'x' ms

% System CPU Usage (by Processor)

Network Usage (bytes sent/received)

I've put a LOT of work into this project, and all I ask is that you follow my License Agreement when using the code (very easy, see below). Any feedback is welcome. I apologize for the unpolished GUI interfaces (especially the unfinished one), but I will get to that TaskManager GUI one day, hah. Enough chatter -now go on and experience the awesome power of Performance Counters :P

Download the ZIP Here

NOTE: Bundled in the ZIP (and included in the License agreement) are other UDF's I wrote that are necessary to run some of the 'Test' programs:

_WinAPI_GetSystemInfo.au3, _WinAPI_GetPerformanceInfo.au3, _WinTimeFunctions.au3, and the unnecessary, but provided for those who are interested in the _WinTimeFunctions 'filetime' usage, program: TestWinTimeFunctions.au3.

Ascend4nt's AutoIT Code License agreement:

While I provide this source code freely, if you do use the code in your projects, all I ask is that:

  • If you provide source, keep the header as I have put it, OR, if you expand it, then at least acknowledge me as the original author, and any other authors I credit
  • If the program is released, acknowledge me in your credits (it doesn't have to state which functions came from me, though again if the source is provided - see #1)
  • The source on it's own (as opposed to part of a project) can not be posted unless a link to the page(s) where the code were retrieved from is provided and a message stating that the latest updates will be available on the page(s) linked to.
  • Pieces of the code can however be discussed on the threads where Ascend4nt has posted the code without worrying about further linking.
Enjoy!

Ascend4nt

UPDATES:

  • 10/12/2012:

    - Fix: For systems with >64 processors, wrong results were returned for the # of CPU's. A new test is run using 'GetActiveProcessorCount' (Win7+/2008R2+) to get the total number of logical processors in ALL processor groups

  • 6/2/2011:

    - MS Bugs found: _PDH_BrowseCounters() on Win7 causes around 40 DLL's to STAY loaded after the API call. Plus, reference count to PDH.DLL is increased by 2.

    Workaround: Don't use this function unless ABSOLUTELY necessary!

    However, using _PDH_ReloadDLL() can cut down on the # of DLL's that are loaded (to around 10 on my system) but note that subsequent calls to _PDH_BrowseCounter() will be slower!

    - Added: _PDH_ReloadDLL(). I found a bug with these API calls (Win2000->Win7):

    * PdhExpandWildCardPath [_PDH_GetCounterList()]

    * PdhValidatePathW [_PDH_ValidatePath()]

    Neither of the above recognize new object instances unless PDH.DLL is unloaded! Hence, _PDH_ReloadDLL() is there to fix this issue.

    *NOTE: Use of this will cause subsequent _PDH_BrowseCounters() call's to take a long time to load, unless previous calls weren't made.

    - Added: Internal function __PDH_ForceFreeDLL() -> to support _PDH_ReloadDLL(), and maybe fix 'Browse Counters Dialog' problems in the future

    - Changed: TestPDH_PerformanceCounters() now calls _PDH_ReloadDLL() to allow it to 'see' new instances when Manual Entry is used.

    - Changed: TestPDH_PerformanceCounters() now recognizes all-counters-dead scenarios.

    - Fix: _PDH_GetCounterInfo() on Win2000 was broken.

    - Fix: _WinTime_Format* functions handling of Milliseconds - was padding to 4 character instead of 3 characters long (Thx Joakim)

  • 5/28/2011:

    - Fixed: Bug introduced in last version: Single-item selection in 'Browse Counters Dialog' returning cut-off strings.

    - Fixed: _ProcessAll* UDF function had misspelling

    - Fixed: The 'Browse Counters Dialog' doesn't display instances in some weird cases. TestPDH_PerformanceCounters now deals with this properly

    - Change: TestPDH_TaskManager title reflects static nature of UDF.

    - Change: Removed PC Name parameter from _PDH_Init(). Don't know what I was thinking.

    - Change: DEBUG information defaults to error-only mode now. Set $PDH_DEBUG to 2 to show ALL Debug info

    - Change: All examples (save for one) now follow the 'baseline-sleep' model for collecting data (not always needed)

    - Added: _PDH_ObjectBaseCollectQueryData(), _PDH_ProcessObjectCollectQueryData(), & _PDH_ProcessAllCollectQueryData() (to better support baseline-sleep)

  • 5/22/2011

    - New UDF: PDH_HardDiskUsageExample.au3

    - _PDH_PerformanceCounters.au3 UDF changes:

    - Added:

    _PDH_RegistryCheck(), _PDH_RegistryEnable(), and _PDH_RegistryDisable() -> to allow checking & altering Performance Counter availability on local OR Remote PC. Note that ADMIN rights are req'd for making changes.

    - Changed:

    _PDH_Init() & _PDH_UnInit altered to work with new Registry modification code

    _PDH_Init() now takes 3 optional parameters regarding Registry state (force registry on, restore on exit, PC Name)

    _PDH_BrowseCounters() - added new parameters to allow customization, now allows multiple selections to be returned in an array

    - Fixed:

    _PDH_BrowseCounters() - default title was not showing for Win7

    _PDH_GetCounterList() - Wildcard sanity-check fixed for special cases where a * is part of the Instance name

  • 8/19/2010:

    - Fixed: _PDH_UnInit() was looking for parameters when called On-Exit

    - Fixed: _PDH_ObjectBaseCreate -> Logic error if Couldn't get counters from given PCNAME

    - Fixed: Extra Registry value found that could disable Performance Counters, changed registry save/restore code

    - Updated: _PDH_PerformanceCounter_Notes.txt (requirements)

    - Changed: Core Module: _PDH_Init() registers _PDH_UnInit() as an on-exit function (and _PDH_UnInit() unregisters itself)

    - Added: Core: _PDH_ConnectMachine() - connects to the given machine (really only adds the name to the dropdown box in BrowseCounters calls)

    - Added: _PDH_ProcessCounters Module: two wrapper functions: _PDH_ProcessObjectGetPID() and _PDH_ProcessObjectGetName()

    -> More Examples Added <-:

    TestPDH_ProcessCounter, TestPDH_ProcessCounterPoll, TestPDH_ProcessMultipleInstanceMonitor, TestPDH_HDDWaitIdle, TestPDH_CPUUsage, TestPDH_NetworkUsage

  • 7/2/2010 (MASSIVE Update):

    _PDH_PerformanceCounters core module:

    - Fixed: PCRE "% Processor Usage" detection in 'Update' functions to work with nonlocalized counter strings. NOTE: will not work on localized non-English Counters (forcing it with a 'path' of -2 works here)

    - Fixed: _PDH_GetCounterInfo now works correctly on Windows 2000 (return message discrepancy)

    - Changed: _PDH_UpdateCounterArray now retrieves null-term strings the (better) way.

    - Changed: _PDH_FreeQueryHandle now returns False when there is an error condition returned,

    and also if successful now invalidates the passed Query Handle.

    NOTE _PDH_UnInit() will *not* invalidate any (optional) passed Query handles - they will retain their values

    - Changed: _PDH_RemoveCounter also now invalidates the passed Counter Handle

    - Changed: _PDH_UpdateCounterArray => renamed to => _PDH_UpdateWildcardCounter

    - Changed: __PDH_LocalizeCounter() now works with non-localized counters ending in slash but with no PC name

    - Removed: Comments and error codes extracted and put in two separate text files:

    _PDH_Error_Codes.txt (the PDH codes you'll see in the console window and in @extended returns)

    _PDH_PerformanceCounter_Notes.txt - Some personal notes/references about the PDH process project

    - Removed extraneous Wrapper functions (if you need these, see the older version):

    _PDH_AddCountersTo2DArray() ; needless wrapper function

    _PDH_GetCounterValuesByPathArrays() ; needless wrapper function

    TestPDH_PerformanceCounters GUI:

    - Changed default 'convert to all instances' behavior to instead work only on what is returned from the Browse Counter Dialoag box. If you still want *all* instances, just select 'All instances' from the Dialog box.

    _PDH_ProcessStats module removed. The 3 'ObjectBase' modules can be used in place of this.

    TestPDH_Multi => renamed to => TestPDH_ProcessLoop (also utilizes new interface)

    _PDH_TaskMgrPerfStats => renamed to => _PDH_TaskMgrSysStats (with some changes)

    _PDH_ProcessGetRelatives:

    - Changed: utilizes <_PDH_ObjectBaseCounters.au3> now

    - Added: _PDH_ProcessList() -> simple list that should report on ANY PC (but mind the '.exe' issue)

    (see TestPDH_ProcessLoop on how to get the *local* PC Processes info)

    - Return style changed for both _PDH_ProcessGetParent() and _PDH_ProcessGetChildren(), to keep consistency in returns. ([0]=name,[1]=PID#)

    _PDH_AddProcessCounter module removed. Instead use <_PDH_ProcessCounters.au3>

    Addition of 3 new modules (plus a simple example) to make adding Counters with the same Base Object easier:

    _PDH_ObjectBaseCounters -> for Counters that have the same base and use an Instance name or Wildcard

    _PDH_ProcessCounters -> for single processes, 1 or more Counters [Local PC only]

    These functions will monitor 'Instance' changes and readjust Counters as needed.

    (MUCH easier and safer implementation than previous _PDH_AddProcessCounter UDF)

    _PDH_ProcessAllCounters -> for ALL processes, 1 or more Counters [Local PC only]

    + minor misc. changes, alterations in some UDF's to work with new interfaces.

  • 6/20/2010:

    - Added new module: _PDH_AddProcessCounter.au3, to make adding single Process Counters easier

    - Added a test of the new module 'TestPDH_ProcessCounter.au3'. This will have to be manually edited to test other Processes other than 'autoit3.exe'

    - Updated TestPDH_PerformanceCounters to now display "Non-Localized Counter Path *with* PC Name"

  • 5/18/2010: Localization issues should be fixed. New function _PDH_CounterNameToNonLocalStr() creates a special string that can be used to create counters for other languages.

    - Two support functions were added in addition to the above

    - _PDH_GetCounterInfo() now returns an array.

    - TestPDH_PerformanceCounters now provides better output on the bottom.

    *Also fixed PCRE issue with multiple parentheses.

  • 5/14/2010: x64 Compatibility is Fixed!
  • 5/9/2010: Releasing W-I-P since I feel the need for this is out there, even if the project is not complete.

    Note that there are extra modules includes for the 'Test' programs (_WinAPI_GetPerformanceInfo.au3, _WinAPI_GetSystemInfo.au3, _WinTimeFunctions.au3, and the unnecessary TestWinTimeFunctions.au3)

  • 5/09-5/2010 Updates: Added extra _PDH extended info modules, more functions in general (lost track, sorry), new Test programs, etc.

    - Bottom edit box now displays appropriate 'GetCounterInfo' for selected Counter Handle in listview.

  • 4/1/09 Update: Wildcard Counters support.
  • 3/7/09:

    New:

    !! CPU Usage now reports correct % (based on comparisons with Task Manager)!!

    New functionality:

    TEST_PDH_PerformanceCounters now allows Manual entry for more experimentation

    Added functions:

    _PDH_RemoveCounter()

    _PDH_UpdateCounter()

    Also added from another UDF (just to keep file count down):

    _WinAPI_GetSystemInfo() - for CPU count

    Altered functions:

    PDH_Init() now initializes CPU totals

    PDH_UpdateCounters() changed to test for CPU usage Counters and adjust according to # of CPU's

    (PDH_UpdateCounter() has the same functionality)

    _PDH_AddCountersByArray() altered slightly in that the 'bottom rows' parameter is a count rather than a bool.

    - *misc* other changes

Edited by Ascend4nt
Link to comment
Share on other sites

You should be able to. I made sure in the Browse Counters function to not set the 'local computer only' flag. Give it a try, let me know.

*edit- err, you did mean networked pc's right?

Edited by ascendant
Link to comment
Share on other sites

That was really frickin cool, ascendant! :P

Great job on packaging too!

/Manko

Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...
Link to comment
Share on other sites

You should be able to. I made sure in the Browse Counters function to not set the 'local computer only' flag. Give it a try, let me know.

*edit- err, you did mean networked pc's right?

Yep. You can use WMI for getting the counter from remote systems, e.g. servers.

I'm planning to implement performance counters to my sic project but until now I was just planning... :P

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

That was really frickin cool, ascendant! :P

Great job on packaging too!

/Manko

Thanks! haha.. I thought it was pretty cool too once I added the function to interact with the 'Browse Counters' dialog. I was like wow - I never imagined so much information was available.

Hey - have you tried the Process - %Processor Time Counter? I've tested this and the results don't match Task Manager. I'm thinking this *might* have something to do with multi-core processors? I'd have to take another look at one of the sources I used to see if there's a better method of calculating that properly.

-A

Link to comment
Share on other sites

..

This is indead a small master piece :P

I consider that a very high compliment. Thanks :unsure:

btw, there's *other* Counters that my functions don't cover - namely ones dealing with log files. Also, I prevented the 'Browse Counters Dialog' from displaying Counters considered 'Costly' - but that can easily be changed by adjusting the flags in that function. I'd be curious what those Counters are, but I'm guessing they aren't something you'd normally want to mess with due to the resource requirements..

Link to comment
Share on other sites

Updated!! CPU % Usage now reports values correctly! Finally, a person can create a Task Manager with this and a few other modules (without even touching WMI!) :P w00t!

Added a few other things - including manual entry in the GUI, new functions, etc..

More comprehensive list of updates/changes is in 1st post

Link to comment
Share on other sites

Updated!! CPU % Usage now reports values correctly!

Great! What did you do to fix it? What was the problem?

/Manko

Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...
Link to comment
Share on other sites

Great! What did you do to fix it? What was the problem?

/Manko

Well, 2 things - I didn't set the 'PDH_FMT_NOCAP100' flag initially when calling 'PdhGetFormattedCounterValue', and 2nd I needed to divide the results (for only CPU usage counters) by the # of system reported CPU's. (I have a quad-core CPU btw - so once I set the 'NOCAP' flag, I was getting 400% usage total counts, which of course needed to be divided by 4).

Link to comment
Share on other sites

  • 1 year later...

Okay, I decided to release the PDH Performance Counters project in its current Work-in-Progress state. There's a lot of stuff to this project, and I hope to document it in the future, but for now you sorta have to make do. The test examples might help understand this better, and any questions I can probably help with. Again, I remind you, this is a W-I-P version, so there's a lot of stuff that needs refining, updating, and possibly x64 modifications.

NOTE also: Bundled in the ZIP [see first post] (and included in the License agreement) are other UDF's I wrote that are necessary to run some of the 'Test' programs:

_WinAPI_GetSystemInfo.au3, _WinAPI_GetPerformanceInfo.au3, _WinTimeFunctions.au3, and the unnecessary, but provided for those who are interested in the _WinTimeFunctions 'filetime' usage, program: TestWinTimeFunctions.au3.

UPDATES:

  • 5/9/2010: Releasing W-I-P since I feel the need for this is out there, even if the project is not complete.

    Note that there are extra modules includes for the 'Test' programs (_WinAPI_GetPerformanceInfo.au3, _WinAPI_GetSystemInfo.au3, _WinTimeFunctions.au3, and the unnecessary TestWinTimeFunctions.au3)

  • 5/09-5/2010 Updates: Added extra _PDH extended info modules, more functions in general (lost track, sorry), new Test programs, etc.

    - Bottom edit box now displays appropriate 'GetCounterInfo' for selected Counter Handle in listview.

  • 4/1/09 Update: Wildcard Counters support.
Link to comment
Share on other sites

Okay, x64 compatibility issues have been resolved. However, there is a strange issue with the 'Browse Counters' dialog box, most likely not related to any structure/size issues. It's *possibly* an issue with the 64-bit version of PDH.DLL, but I cannot yet be certain of where the issue lies.

Here's the deal: selecting any single object in a Counter with multiple instances (Processes for example) returns 'success', but NO string is returned - and GetLastError reports success! HOWEVER, select '<All instances>', and it returns a string. Go figure!

I haven't tested this on Win7 x64 yet, and haven't updated my Vista x64 test O/S to the latest fixes, so I would appreciate any testing anyone can do!

Updates:

  • 5/14/2010: x64 Compatibility Fixes. However, 'Browse Counters' dialog box has issues selecting some Counters. This may be an issue with PDH.DLL or something else (?).
Edited by Ascend4nt
Link to comment
Share on other sites

BTW seems _WinAPI_GetSystemInfo.au3 missing?

D'oh!! Sorry about that - I included the wrong file in the ZIP (_WinAPI_GetSystemTimes, oops). It should be fixed now.

Note to self: Test these projects in a separate folder before uploading!!

Link to comment
Share on other sites

Update:

*x64 Issues have finally been resolved completely!*

Yay!! Stupid bugger of a problem to find.. turns out there's just one flag that shouldn't be set on the Browse Counters dialog box for Vista+ O/S's.

I removed the 'W-I-P' part of the project title since it is now completely usable on any O/S Win2000+ in any bit-mode.

However, though the core PDH functions are good, other parts of the project can be considered Works-in-Progress. For one, the examples need to be completed (as in, they should update/refresh information). I also should probably rework some of the code in the extended PDH modules.

Otherwise, its all good. Of course, I'll be doing additional modifications of the core PDH module in the future too (namely - removing a few wrapper functions, altering one or two functions, and probably providing more options for some functions). But until then, happy 'Performance Counting'!

Edited by Ascend4nt
Link to comment
Share on other sites

Hi m8,

thanks for this (as always :) ) great UDF. I wanted to utilize it in one of my projects, but ran into this error

CPU count result:4
_PDH_GetNewQueryHandle Call succeeded, return:0,param1:0x0000000000000000,param2:0,handle:0x00000000044112F0
PdhAddCounterW error [path:'\Process(*)\ID Process'], return:C0000BB8
PdhAddCounterW error [path:'\Process(*)\Creating Process ID'], return:C0000BB8
PdhCloseQuery DLL call successful
Time for _PDH_ProcessGetChildren():456.555864370802 ms
All (3) Child processes found via PDH for PID#4120:

[Original PID's retrieved from Run() :5624]

trying this code

#include <PDHPerfCounters\_PDH_ProcessGetRelatives.au3>

$iPID = Run("control mmsys.cpl", "", @SW_HIDE)
$iTimer = TimerInit()
$aChildProcesses = _PDH_ProcessGetChildren()
Local $iExt = @extended
ConsoleWrite("Time for _PDH_ProcessGetChildren():" & TimerDiff($iTimer) & " ms" & @CRLF)
If $iExt = 0 Then
    ConsoleWrite("No Child Processes found for PID#" & @AutoItPID & @CRLF)
Else
    ProcessClose($iPID)
    Local $sOutputStr = ""
    For $i = 0 To UBound($aChildProcesses) - 1
        $sOutputStr &= "Child Process found: Process ID#" & $aChildProcesses[$i][0] & ", name: '" & $aChildProcesses[$i][1] & "'" & @CRLF
    Next
    $sOutputStr &= @CRLF & "[Original PID's retrieved from Run(): " & $iPID & "]"
    ConsoleWrite("All (" & $iExt & ") Child processes found via PDH for PID#" & @AutoItPID & ':' & @CRLF & $sOutputStr & @CRLF)
    MsgBox(0, "(" & $iExt & ") Child Processes found via PDH for PID#" & @AutoItPID & ' (all closed):', $sOutputStr)
EndIf

Win7 64bit Ultimate, maybe you'll find time to take a look :idea: ...

Edited by KaFu
Link to comment
Share on other sites

Well darn, if only I installed Win7 x64 so I could test this there. So far, the code you posted executed fine for me on Vista x64 (both 32-bit and 64-bit modes) and Win7 x86, but I don't yet have an install of Win7 x64 to test. (need to make room for it argh)

Okay.. before I go crazy and clear out space and install the O/S, do me a favor and look in your registry at these keys:

"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PerfOS\Performance"

"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PerfProc\Performance"

See if they exist and this value exists (and what it is set to):

"Disable Performance Counters"

My 'Init' routine looks at those keys and *should* try to enable performance counters if that value exists, but it would probably give UAC prompts.

Also - a note on the code - the value you are getting in $iExt is an extended error code (probably the same as $_PDH_iLastError). I'm not sure what the context is - you'd have to add an @error check and output it.

However - the 'PdhAddCounterW' code in your output (C0000BB8) is defined as PDH_CSTATUS_NO_OBJECT, which MSDN defines as 'Unable to find the specified object on the computer or in the log file.'

Looking further, it looks like this *may* be a problem with non-English versions of Windows. (Perhaps you have a foreign language version installed?)

Per user comments on 'PdhAddCounterFunction' on MSDN, "The counter path specified in szFullCounterPath should be localized, or the function may fail on non-English versions of Windows."

If you'd be so kind, and if it is a non-English version of Windows you are using, could you try replacing 'PdhAddCounterW' in the DLLCall in the '_PDH_PerformanceCounters' module with 'PdhAddEnglishCounterW'? All the other parameters should remain the same. This function is a Vista+ function, so I might have to add a @OSVersion check before this call.

Sorry to put you to work, but hey - I'll be very grateful! Thanks in advance!

*edit: also, do me a favor and see what keys are under this key in your registry:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib

(I only have 009 (English))

Edited by Ascend4nt
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...