PDH - Performance Counters

Post your working scripts, libraries and tools.
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

PDH - Performance Counters

Post by jNizM » 24 May 2022, 07:03

Small examples, how to work with PDH (https://docs.microsoft.com/en-us/windows/win32/perfctrs/performance-counters-portal).
Windows Performance Counters provide a high-level abstraction layer that provides a consistent interface for collecting various kinds of system data such as CPU, memory, and disk usage. System administrators often use performance counters to monitor systems for performance or behavior problems. Software developers often use performance counters to examine the resource usage of their programs.

Code: Select all

ERROR_SUCCESS  := 0
PDH_FMT_LONG   := 0x00000100
PDH_FMT_DOUBLE := 0x00000200
PDH_FMT_LARGE  := 0x00000400

; ===========================================================================================================================================================================

Main := Gui(, "PDH - Performance Counters")
Main.MarginX := 10
Main.MarginY := 10

Main.SetFont("s10", "Courier New")

Main.AddText("xm ym w350 h25 0x200", "\Processor(_Total)\% Processor Time")
ED1 := Main.AddEdit("x+5 yp w150 0x802")

Main.AddText("xm y+2 w350 h25 0x200", "\Memory\Available Bytes  (calc. in GB)")
ED2 := Main.AddEdit("x+5 yp w150 0x802")

Main.AddText("xm y+2 w350 h25 0x200", "\Memory\Committed Bytes  (calc. in GB)")
ED3 := Main.AddEdit("x+5 yp w150 0x802")

Main.AddText("xm y+2 w350 h25 0x200", "\Network Interface(*)\Bytes Sent/sec")
ED4 := Main.AddEdit("x+5 yp w150 0x802")

Main.AddText("xm y+2 w350 h25 0x200", "\Network Interface(*)\Bytes Received/sec")
ED5 := Main.AddEdit("x+5 yp w150 0x802")

Main.AddText("xm y+2 w350 h25 0x200", "\Thermal Zone Information(*)\Temperature")
ED6 := Main.AddEdit("x+5 yp w150 0x802")

Main.OnEvent("Close", CleanUp)
Main.Show()

; ===========================================================================================================================================================================

#DllLoad "pdh.dll"

if (PDH_STATUS := DllCall("pdh\PdhOpenQuery", "Ptr", 0, "UPtr", 0, "Ptr*", &hQuery := 0, "UInt") != ERROR_SUCCESS)
	MsgBox "PdhOpenQuery failed with " PDH_STATUS

if (PDH_STATUS := DllCall("pdh\PdhAddEnglishCounter", "Ptr", hQuery, "Str", "\Processor(_Total)\% Processor Time", "UPtr", 0, "Ptr*", &hCounter1 := 0, "UInt") != ERROR_SUCCESS)
	MsgBox "PdhAddEnglishCounter failed with " PDH_STATUS

if (PDH_STATUS := DllCall("pdh\PdhAddEnglishCounter", "Ptr", hQuery, "Str", "\Memory\Available Bytes", "UPtr", 0, "Ptr*", &hCounter2 := 0, "UInt") != ERROR_SUCCESS)
	MsgBox "PdhAddEnglishCounter failed with " PDH_STATUS

if (PDH_STATUS := DllCall("pdh\PdhAddEnglishCounter", "Ptr", hQuery, "Str", "\Memory\Committed Bytes", "UPtr", 0, "Ptr*", &hCounter3 := 0, "UInt") != ERROR_SUCCESS)
	MsgBox "PdhAddEnglishCounter failed with " PDH_STATUS

if (PDH_STATUS := DllCall("pdh\PdhAddEnglishCounter", "Ptr", hQuery, "Str", "\Network Interface(*)\Bytes Sent/sec", "UPtr", 0, "Ptr*", &hCounter4 := 0, "UInt") != ERROR_SUCCESS)
	MsgBox "PdhAddEnglishCounter failed with " PDH_STATUS

if (PDH_STATUS := DllCall("pdh\PdhAddEnglishCounter", "Ptr", hQuery, "Str", "\Network Interface(*)\Bytes Received/sec", "UPtr", 0, "Ptr*", &hCounter5 := 0, "UInt") != ERROR_SUCCESS)
	MsgBox "PdhAddEnglishCounter failed with " PDH_STATUS

if (PDH_STATUS := DllCall("pdh\PdhAddEnglishCounter", "Ptr", hQuery, "Str", "\Thermal Zone Information(*)\Temperature", "UPtr", 0, "Ptr*", &hCounter6 := 0, "UInt") != ERROR_SUCCESS)
	MsgBox "PdhAddEnglishCounter failed with " PDH_STATUS

if (PDH_STATUS := DllCall("pdh\PdhCollectQueryData", "Ptr", hQuery, "UInt") != ERROR_SUCCESS)
	MsgBox "PdhCollectQueryData failed with " PDH_STATUS

while (PDH_STATUS = ERROR_SUCCESS)
{
	PDH_STATUS := DllCall("pdh\PdhCollectQueryData", "Ptr", hQuery, "UInt")

	if (PDH_STATUS = ERROR_SUCCESS)
	{
		Value := Buffer(16, 0)
		if (PDH_STATUS := DllCall("pdh\PdhGetFormattedCounterValue", "Ptr", hCounter1, "UInt", PDH_FMT_DOUBLE, "Ptr", 0, "Ptr", Value, "UInt") != ERROR_SUCCESS)
			MsgBox "PdhGetFormattedCounterValue failed with " PDH_STATUS
		ED1.Value := Format("{1:0.2f}", NumGet(Value, 8, "Double"))

		Value := Buffer(16, 0)
		if (PDH_STATUS := DllCall("pdh\PdhGetFormattedCounterValue", "Ptr", hCounter2, "UInt", PDH_FMT_LARGE, "Ptr", 0, "Ptr", Value, "UInt") != ERROR_SUCCESS)
			MsgBox "PdhGetFormattedCounterValue failed with " PDH_STATUS
		ED2.Value := Format("{1:0.2f}", NumGet(Value, 8, "Int64") / 1024**3)

		Value := Buffer(16, 0)
		if (PDH_STATUS := DllCall("pdh\PdhGetFormattedCounterValue", "Ptr", hCounter3, "UInt", PDH_FMT_LARGE, "Ptr", 0, "Ptr", Value, "UInt") != ERROR_SUCCESS)
			MsgBox "PdhGetFormattedCounterValue failed with " PDH_STATUS
		ED3.Value := Format("{1:0.2f}", NumGet(Value, 8, "Int64") / 1024**3)

		Value := Buffer(16, 0)
		if (PDH_STATUS := DllCall("pdh\PdhGetFormattedCounterValue", "Ptr", hCounter4, "UInt", PDH_FMT_LARGE, "Ptr", 0, "Ptr", Value, "UInt") != ERROR_SUCCESS)
			MsgBox "PdhGetFormattedCounterValue failed with " PDH_STATUS
		ED4.Value := NumGet(Value, 8, "Int64")

		Value := Buffer(16, 0)
		if (PDH_STATUS := DllCall("pdh\PdhGetFormattedCounterValue", "Ptr", hCounter5, "UInt", PDH_FMT_LARGE, "Ptr", 0, "Ptr", Value, "UInt") != ERROR_SUCCESS)
			MsgBox "PdhGetFormattedCounterValue failed with " PDH_STATUS
		ED5.Value := NumGet(Value, 8, "Int64")

		Value := Buffer(16, 0)
		if (PDH_STATUS := DllCall("pdh\PdhGetFormattedCounterValue", "Ptr", hCounter6, "UInt", PDH_FMT_DOUBLE, "Ptr", 0, "Ptr", Value, "UInt") != ERROR_SUCCESS)
			MsgBox "PdhGetFormattedCounterValue failed with " PDH_STATUS
		ED6.Value := Format("{1:0.2f}", NumGet(Value, 8, "Double") - 273.15)
	}

	sleep 1000
}

; ===========================================================================================================================================================================

CleanUp(*)
{
	if (hQuery)
		DllCall("pdh\PdhCloseQuery", "Ptr", hQuery)
}
Image

A few more examples:

Code: Select all

"\Process(_Total)\Handle Count"
"\Process(_Total)\Thread Count"
"\Process(notepad)\% Processor Time"
"\Process(outlook)\Working Set"
"\Process(firefox)\Private Bytes"

Under the Counter registry entry in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009 you can find all counters supported by the system

With Powershell you can also get an overview:
Get-Counter -ListSet * | Sort-Object -Property CounterSetName | Select CounterSetName

The string is structured as follows -> https://docs.microsoft.com/en-us/windows/win32/perfctrs/specifying-a-counter-path
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile

User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: PDH - Performance Counters

Post by TheArkive » 02 Jun 2022, 13:28

Very nicely done jNizM! I like this. :bravo:

Post Reply

Return to “Scripts and Functions (v2)”