Sean wrote:
It's explained in the post.
So it is, sorry for that, I didn't think to use that.
Sean wrote:
BTW, you're confused between Item of SWbemRefresher and Item of SWbemObjectSet which should be passed a string.
Ah yes, sorry I meant to link
here instead, which says there should be an Item method, no?
Anyway, if you advise it will be slower, I will use the "_NewEnum" way you suggested instead.
I used this in the below code (which is working BTW), but it seems that I have to refresh twice to get the values (probably for the same
reason as I linked in my second post?) and also without a sleep of about 500ms-1 second between the refreshes, strange values come back...
Anyway if anyone is interested, here is the code I ended up with. Thanks
Sean for all your help (once again)

I will probably get round to making a more useful version of this and posting it, but this will be OK for now.
Please bear in mind that the second MsgBox showing both 'used' and 'idle' percentages is just a demo... you will probably find that they don't add up to 100% due to them being from different refreshes. They may not even add up to 100% when the parameter "all" is passed (maybe due to rounding issues) but the Idle and Total values should be OK, meaning you can use them to get values that add up to 100%.
Code:
#NoEnv
OnExit, ExitSub
Hotkey, Esc, ExitSub
COM_Init()
MsgBox, % "##### ALL PROCESSES #####:`n`n" . GetCPUTime("all")
MsgBox, % "Called Separately (these values may not add up to 100%!):`n`nCPU Usage = " . GetCPUTime("used") . "%`nIdle: " . GetCPUTime("idle") . "%"
SetTimer, ShowCPUTip, 1000 ; will show a tip with the correct values for Used, Idle and _Total (which will add up to 100% as they are from the same refresh)
GoSub, ShowCPUTip
Return
ShowCPUTip:
CPUVals := GetCPUTime("all")
Loop, Parse, CPUVals , `n, `r
{
Loop, Parse, A_LoopField, `:
{
If ( A_Index = 1 )
ProcName := A_LoopField
Else If ( A_Index = 2 )
ProcVal := A_LoopField
}
If ( ProcName = "_Total" or ProcName = "Idle" )
%ProcName% := ProcVal
}
Used := _Total - Idle ; should be what is used
ToolTip, % "CPU Used: " Used "%`nIdle: " Idle "%`n_Total: " _Total "%"
Return
Esc::
ExitSub:
COM_Term()
ExitApp
Return
;####################################################################
;####################################################################
GetCPUTime(ReqType="used")
{
; Returns various values about CPU usage.
; default is to return the percent used = ( _Total - Idle )
; possible values are "used", "idle" or "all"
; the first 2 will return a single integer value
; and "all" will return a list of all
; enumerated processed found in the form:
; Name1:Value1`nName2:Value2
Namespace := "root\cimv2"
Class := "Win32_PerfFormattedData_PerfProc_Process"
objWMIService := COM_GetObject("winmgmts:\\." . Namespace)
objRefresher := COM_CreateObject("WbemScripting.SWbemRefresher")
colItems := COM_Invoke(COM_Invoke(objRefresher, "AddEnum", "+" objWMIService, Class), "objectSet")
; the need to refresh twice is explained here:
COM_Invoke(objRefresher, "Refresh") ; have to refresh first, only get values on the second refresh.
Sleep, 500 ; for some reason, values come back strangely if there is no sleep here, I found 500-1000ms seems to be best...
sMsgTxt := "", IdleTime := "", TotalTime := ""
COM_Invoke(objRefresher, "Refresh")
oEnum := COM_Invoke(colItems, "_NewEnum")
While( COM_Enumerate(oEnum, pItm) = 0 )
{
ItemName := COM_Invoke(pItm, "Name")
ItemVal := COM_Invoke(pItm, "PercentProcessorTime")
If ( ItemName = "Idle" )
IdleTime := ItemVal
Else If ( ItemName = "_Total" )
TotalTime := ItemVal
AllTime .= ItemName . ":" . ItemVal . "`n"
}
COM_Release(oEnum), oEnum := 0
If ( ReqType = "used" )
ReturnVal := TotalTime - IdleTime ; used cpu time
Else If ( ReqType = "idle" )
ReturnVal := IdleTime
Else If ( ReqType = "all" )
ReturnVal := AllTime
COM_Release(objWMIService), objWMIService := 0
COM_Release(objRefresher), objRefresher := 0
COM_Release(colItems), colItems := 0
Return IdleTime != "" ? ReturnVal : -1 ; -1 means there was a problem
}