SetBatchLines, -1 SetFormat, float, 0.0 CoordMode, ToolTip, screen period = 1000 loop { idleTime = idleTime1 GetIdleTime( idleTime ) start := a_TickCount Sleep, %period% elapsed := a_TickCount-start idleTime = idleTime2 GetIdleTime( idleTime ) total_idle_ticks := ( idleTime2?ticks_high-idleTime1?ticks_high ) << 32 total_idle_ticks := total_idle_ticks+( idleTime2?ticks_low-idleTime1?ticks_low ) total_idle_ticks := total_idle_ticks*0.0001 ppu_idle := total_idle_ticks/elapsed*100 total := elapsed-total_idle_ticks ppu := 100-ppu_idle ToolTip, period = %period% (ideal)`nelapsed = %elapsed% (actual)`n`nppu = %total% ms (%ppu%`%)`nidle = %total_idle_ticks% ms (%ppu_idle%`%), 10, 10 } ReadInteger( p_address, p_offset, p_size, p_hex=true ) { old_FormatInteger := a_FormatInteger if ( p_hex ) SetFormat, integer, hex else SetFormat, integer, dec value = 0 loop, %p_size% value := value+( *( ( p_address+p_offset )+( a_Index-1 ) ) << ( 8* ( a_Index-1 ) ) ) SetFormat, integer, %old_FormatInteger% return, value } GetIdleTime( p_IdleTime ) { global local success /* struct FILETIME { DWORD dwLowDateTime; uint4 0 DWORD dwHighDateTime; uint4 4 } */ VarSetCapacity( %p_IdleTime%?ticks, 4+4 ) success := DllCall( "kernel32.dll\GetSystemTimes", "uint", &%p_IdleTime%?ticks, "uint", 0, "uint", 0 ) if ( ! success ) { MsgBox, GetSystemTimes failed! ExitApp } %p_IdleTime%?ticks_low := ReadInteger( &%p_IdleTime%?ticks, 0, 4 ) %p_IdleTime%?ticks_high := ReadInteger( &%p_IdleTime%?ticks, 4, 4 ) }
This method tracks the system idle time (i.e., the OS idle process). The assumption is that processor utilization can be determined by examining the difference between system idle time and elapsed time during any given period.
I have tested this against the "CPU Usage" and "System Idle Process - CPU Usage" statistics as presented by Process Explorer (PE) from SysInternals. In my testing I noticed that this method produces a processor utilization which fairly accurately tracks that given by PE. In fact, this method produces statistics which seem to anticipate that given by PE.
The code above is a proof-of-concept. A preferred implementation would likely use a timer to gather statistics and save them in a temporal list which could later be accessed as needed.
Anyway... no guarantees.