Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[Solved] Get CPU usage in %


  • Please log in to reply
12 replies to this topic
Bruttosozialprodukt
  • Members
  • 457 posts
  • Last active: Oct 18 2015 08:47 AM
  • Joined: 20 Oct 2012

More than one person on the forum stated that GetProcessTimes() would return the cpu usage of a process in %. But that simply doesn't seem to be true:

Gui, Add, ListView, x2 y0 w400 h500, Name|PID|CPU
for process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
    LV_Add("", process.Name, process.processId,"...")
Gui, Show,, Process List

SetTimer, UpdateCpuUsage
Return

UpdateCpuUsage:
    Loop % LV_GetCount() {
        LV_GetText(pid, A_Index, 2)
        cpuUsage := Round(GetProcessTimes(pid)) "%"
        LV_Modify(A_Index, "Col3", cpuUsage)
    }
Return

GetProcessTimes( PID=0 )    {
   Static oldKrnlTime, oldUserTime
   Static newKrnlTime, newUserTime

   oldKrnlTime := newKrnlTime
   oldUserTime := newUserTime

   hProc := DllCall("OpenProcess", "Uint", 0x400, "int", 0, "Uint", pid)
   DllCall("GetProcessTimes", "Uint", hProc, "int64P", CreationTime, "int64P"
           , ExitTime, "int64P", newKrnlTime, "int64P", newUserTime)

   DllCall("CloseHandle", "Uint", hProc)
Return (newKrnlTime-oldKrnlTime + newUserTime-oldUserTime)/10000000 * 100   
}

To be honest I don't really get what this function does at all.

So is there any way to get the cpu usages of all processes, just like the task manager does.



bruno
  • Members
  • 635 posts
  • Last active: Nov 04 2015 02:26 PM
  • Joined: 07 Mar 2011

how about this:? ;)

; http://www.auto-hotkey.com/boards/viewtopic.php?f=6&t=254
; http://weather.yahooapis.com/forecastrss?w=2455920&u=f

; ===================================================================================
; AHK Version ...: AHK_L 1.1.15.00 x64 Unicode
; Win Version ...: Windows 7 Professional x64 SP1
; Description ...: htopmini
; Version .......: v0.8.3
; Modified ......: 2014.04.11-2027
; Author ........: jNizM
; Licence .......: WTFPL (http://www.wtfpl.net/txt/copying/)
; ===================================================================================
;@Ahk2Exe-SetName htopmini
;@Ahk2Exe-SetDescription htopmini
;@Ahk2Exe-SetVersion v0.8.3
;@Ahk2Exe-SetCopyright Copyright (c) 2013-2014`, jNizM
;@Ahk2Exe-SetOrigFilename htopmini.ahk
; ===================================================================================


; ###################################################################################
; ### GLOBAL SETTINGS                                                             ###
; ###################################################################################

;#Warn
#NoEnv
#SingleInstance Force
SetBatchLines -1

global WinTitel     := "htopmini " A_Now
global Today        := A_DD "." A_MM "." A_YYYY
global OldFormat    := A_FormatInteger
global varPerc      := 0
global Weather_ID   := "2455920"			; Yahoo Weather Location ID
global Weather_DG   := "f"				; Celius = c | Fahrenheit = f
global ownPID       := DllCall("Kernel32.dll\GetCurrentProcessId")
global BuildVersion := DllCall("Kernel32.dll\GetVersion") >> 16 & 0xffff


; ###################################################################################
; ### MENU                                                                        ###
; ###################################################################################

Menu, Tray, DeleteAll
Menu, Tray, NoStandard
Menu, Tray, Add, Toggle Percentage, Menu_Percentage
Menu, Tray, Add,
Menu, Tray, Add, Reset Transparency, Menu_Transparency
Menu, Tray, Add, Toggle AlwaysOnTop, Menu_AlwaysOnTop
Menu, Tray, Add, Show/Hide, Menu_ShowHide
Menu, Tray, Add,
Menu, Tray, Add, Exit, Close
Menu, Tray, Default, Show/Hide


; ###################################################################################
; ### GUI MAIN                                                                    ###
; ###################################################################################

MakeGui:
Gui +LastFound -Caption +ToolWindow +hwndhMain
Gui, Margin, 10, 10
Gui, Color, 000000
Gui, Font, cFFFFFF, Consolas
Gui, Add, Text,     xm     ym w250 vTime01
Gui, Add, Text,     xm+260 ym w170 0x202 vTemp01,
Gui, Add, Text,     xm     y+2  w430 h1 0x7

Gui, Font, cFFFFFF,
Gui, Add, Text,     xm     y+4 w30 0x200, CPU:
Gui, Font, c00FF00,
Gui, Add, Text,     xm+40  yp w80 0x202 vCPU1,
Gui, Add, Text,     xm+140 yp   w80 0x202 vCPU2,
Gui, Add, Progress, xm+250 yp+1 w180 h10 BackgroundF0F0F0 vCPU3,
Gui, Add, Text,     xm     y+3  w430 h1 0x7

Gui, Font, cFFFFFF,
Gui, Add, Text,     xm     y+3 w30 0x200, Mem:
Gui, Font, c00FF00,
Gui, Add, Text,     xm+40  yp   w80 0x202 vMEM01,
Gui, Font, cFFFFFF,
Gui, Add, Text,     xm+140 yp   w80 0x202 vMEM02,
Gui, Add, Progress, xm+250 yp+1 w180 h10 BackgroundF0F0F0 vMEM03,
Gui, Font, c000000 s7,
Gui, Add, Text,     xm+250 yp w180 h11 0x202 +BackgroundTrans vMEM04,

Gui, Font, cFFFFFF s8,
Gui, Add, Text,     xm     y+3 w30 0x200, Swp:
Gui, Font, c00FF00,
Gui, Add, Text,     xm+40  yp   w80 0x202 vSWP01,
Gui, Font, cFFFFFF,
Gui, Add, Text,     xm+140 yp   w80 0x202 vSWP02,
Gui, Add, Progress, xm+250 yp+1 w180 h10 BackgroundF0F0F0 vSWP03,
Gui, Font, c000000 s7,
Gui, Add, Text,     xm+250 yp w180 h11 0x202 +BackgroundTrans vSWP04,
Gui, Font, cFFFFFF s8,
Gui, Add, Text,     xm     y+3  w430 h1 0x7

DriveGet, DrvLstFxd, List, FIXED
loop, Parse, DrvLstFxd
{
    Gui, Font, cFFFFFF,
    Gui, Add, Text,     xm     y+1 w30 0x200 gDriveClick, F_%A_Loopfield%:\
    Gui, Font, c00FF00,
    Gui, Add, Text,     xm+40  yp w80 0x202 vD%A_Loopfield%1,
    Gui, Font, cFFFFFF,
    Gui, Add, Text,     xm+140 yp w80 0x202 vD%A_Loopfield%2,
    Gui, Add, Progress, xm+250 yp+1 w180 h10 vD%A_Loopfield%3,
    Gui, Font, c000000 s7,
    Gui, Add, Text,     xm+250 yp w180 h11 0x202 +BackgroundTrans vD%A_Loopfield%4,
    Gui, Font, cFFFFFF s8,
}
DriveGet, DrvLstRmvbl, List, REMOVABLE
loop, Parse, DrvLstRmvbl
{
    Gui, Font, cFFFFFF,
    Gui, Add, Text,     xm     y+1 w30 0x200 gDriveClick, R_%A_Loopfield%:\
    Gui, Font, c00FF00,
    Gui, Add, Text,     xm+40  yp w80 0x202 vD%A_Loopfield%1,
    Gui, Font, cFFFFFF,
    Gui, Add, Text,     xm+140 yp w80 0x202 vD%A_Loopfield%2,
    Gui, Add, Progress, xm+250 yp+1 w180 h10 vD%A_Loopfield%3,
    Gui, Font, c000000 s7,
    Gui, Add, Text,     xm+250 yp w180 h11 0x202 +BackgroundTrans vD%A_Loopfield%4,
    Gui, Font, cFFFFFF s8,
}
DriveGet, DrvLstNtwrk, List, NETWORK
loop, Parse, DrvLstNtwrk
{
    Gui, Font, cFFFFFF,
    Gui, Add, Text,     xm     y+1 w30 0x200 gDriveClick, N_%A_Loopfield%:\
    Gui, Font, c00FF00,
    Gui, Add, Text,     xm+40  yp w80 0x202 vD%A_Loopfield%1,
    Gui, Font, cFFFFFF,
    Gui, Add, Text,     xm+140 yp w80 0x202 vD%A_Loopfield%2,
    Gui, Add, Progress, xm+250 yp+1 w180 h10 vD%A_Loopfield%3,
    Gui, Font, c000000 s7,
    Gui, Add, Text,     xm+250 yp w180 h11 0x202 +BackgroundTrans vD%A_Loopfield%4,
    Gui, Font, cFFFFFF s8,
}
Gui, Add, Text,     xm     y+3  w430 h1 0x7

Gui, Font, cFFFFFF,
Gui, Add, Text,     xm     y+1  w30 0x200, IN/OUT:
Gui, Font, c00FF00,
Gui, Add, Text,     xm+40  yp   w80 0x202 vIN1,
Gui, Font, cFF0000,
Gui, Add, Text,     xm+140 yp   w80 0x202 vOU1,
Gui, Add, Text,     xm     y+3  w430 h1 0x7

Gui, Font, cFFFFFF,
Gui, Add, Text,     xm     y+10 w150 0x200 vOwnMem,
Gui, Add, Button,   xm+240 yp-6 w60 h20 -Theme 0x8000 gClear, Clear
Gui, Add, Button,   xm+305 yp   w60 h20 -Theme 0x8000 gMinimi, Minimize
Gui, Add, Button,   xm+370 yp   w60 h20 -Theme 0x8000 gClose, Close
Gui, Show, % "AutoSize" (htopx ? " x" htopx " y" htopy : ""), % WinTitel
WinSet, Transparent, 170, % WinTitel

SetTimer, UpdateTime, 1000
SetTimer, UpdateWeather, -1000
SetTimer, UpdateCPULoad, -1000
SetTimer, UpdateMemory, -1000
SetTimer, UpdateTraffic, 1000
SetTimer, UpdateDrive, -1000
SetTimer, UpdateMemHtop, -1000

OnMessage(0x201, "WM_LBUTTONDOWN")
OnMessage(0x219, "WM_DEVICECHANGE")

return


; ###################################################################################
; ### SCRIPT                                                                      ###
; ###################################################################################

UpdateTime:
    GuiControl,, Time01, % Today "  " A_Hour ":" A_Min ":" A_Sec " | Up: " GetDurationFormat(A_TickCount / 1000)
return

UpdateWeather:
    url := DownloadToString("http://weather.yahooapis.com/forecastrss?w=" Weather_ID "&u=" Weather_DG)
    RegExMatch(url, "(?<=Weather for )(.*)(?=\<\/description\>\s\<language\>)", varCity)
    RegExMatch(url, "(?<=temp="")(.*)(?=""  date)", varTemp)
    RegExMatch(url, "(?<=temperature="")(.*)(?=""\s*distance)", varUnits)
    GuiControl,, Temp01, % varCity " | " varTemp " °" varUnits
    SetTimer, UpdateWeather, 60000
return

UpdateCPULoad:
    GuiControl,, CPU1, % GetProcessCount() " proc"
    CPU := CPULoad()
    GuiControl,, CPU2, % CPU " % "
    GuiControl, % ((CPU <= "50") ? "+c00FF00" : ((CPU <= "80") ? "+cFFA500" : "+cFF0000")), CPU3
    GuiControl,, CPU3, % CPU
    SetTimer, UpdateCPULoad, 1000
return

UpdateMemory:
    GMSEx := GlobalMemoryStatusEx()
    GMSExM01 := Round(GMSEx[2] / 1024**2, 2)               ; Total Physical Memory in MB
    GMSExM02 := Round(GMSEx[3] / 1024**2, 2)               ; Available Physical Memory in MB
    GMSExM03 := Round(GMSExM01 - GMSExM02, 2)              ; Used Physical Memory in MB
    GMSExM04 := Round(GMSExM03 / GMSExM01 * 100, 2)        ; Used Physical Memory in %
    GMSExS01 := Round(GMSEx[4] / 1024**2, 2)               ; Total PageFile in MB
    GMSExS02 := Round(GMSEx[5] / 1024**2, 2)               ; Available PageFile in MB
    GMSExS03 := Round(GMSExS01 - GMSExS02, 2)              ; Used PageFile in MB
    GMSExS04 := Round(GMSExS03 / GMSExS01 * 100, 2)        ; Used PageFile in %
    
    GuiControl,, MEM01, % GMSExM03 " MB"
    GuiControl,, MEM02, % GMSExM01 " MB"
    GuiControl, % (GMSExM04 <= "75") ? "+c00FF00" : (GMSExM04 <= "90") ? "+cFFA500" : "+cFF0000", MEM03
    GuiControl,, MEM03, % GMSExM04
    GuiControl,, MEM04, % (varPerc = "1") ? GMSExM04 " % " : ""

    GuiControl,, SWP01, % GMSExS03 " MB"
    GuiControl,, SWP02, % GMSExS01 " MB"
    GuiControl, % (GMSExS04 <= "75") ? "+c00FF00" : (GMSExS04 <= "90") ? "+cFFA500" : "+cFF0000", SWP03
    GuiControl,, SWP03, % GMSExS04
    GuiControl,, SWP04, % (varPerc = "1") ? GMSExS04 " % " : ""
    
    SetTimer, UpdateMemory, 2000
return

UpdateDrive:
    loop, Parse, DrvLstFxd
    {
        i := A_LoopField
        DriveGet, cap%i%, Capacity, %i%:\
        DriveSpaceFree, free%i%, %i%:\
        used%i% := cap%i% - free%i%
        perc%i% := used%i% / cap%i% * 100
        GuiControl,, D%i%1, % Round(used%i% / 1024, 2) " GB"
        GuiControl,, D%i%2, % Round(cap%i% / 1024, 2) " GB"
        GuiControl, % "+Range0-" cap%i%, D%i%3
        GuiControl, % (perc%i% <= "80") ? "+c00FF00" : (perc%i% <= "90") ? "+cFFA500" : "+cFF0000", D%i%3
        GuiControl,, D%i%3, % used%i%
        GuiControl,, D%i%4, % (varPerc = "1") ? Round(perc%i%, 2) " % " : ""
    }
    loop, Parse, DrvLstRmvbl
    {
        j := A_LoopField
        DriveGet, cap%j%, Capacity, %j%:\
        DriveSpaceFree, free%j%, %j%:\
        used%j% := cap%j% - free%j%
        perc%j% := used%j% / cap%j% * 100
        GuiControl,, D%j%1, % Round(used%j% / 1024, 2) " GB"
        GuiControl,, D%j%2, % Round(cap%j% / 1024, 2) " GB"
        GuiControl, % "+Range0-" cap%j%, D%j%3
        GuiControl, % (perc%j% <= "80") ? "+c00FF00" : (perc%j% <= "90") ? "+cFFA500" : "+cFF0000", D%j%3
        GuiControl,, D%j%3, % used%j%
        GuiControl,, D%j%4, % (varPerc = "1") ? Round(perc%j%, 2) " % " : ""
    }
    loop, Parse, DrvLstNtwrk
    {
        k := A_LoopField
        DriveGet, cap%k%, Capacity, %k%:\
        DriveSpaceFree, free%k%, %k%:\
        used%k% := cap%k% - free%k%
        perc%k% := used%k% / cap%k% * 100
        GuiControl,, D%k%1, % Round(used%k% / 1024, 2) " GB"
        GuiControl,, D%k%2, % Round(cap%k% / 1024, 2) " GB"
        GuiControl, % "+Range0-" cap%k%, D%k%3
        GuiControl, % (perc%k% <= "80") ? "+c00FF00" : (perc%k% <= "90") ? "+cFFA500" : "+cFF0000", D%k%3
        GuiControl,, D%k%3, % used%k%
        GuiControl,, D%k%4, % (varPerc = "1") ? Round(perc%k%, 2) " % " : ""
    }
    SetTimer, UpdateDrive, 5000
return

UpdateTraffic:
    dnNew := 0
    upNew := 0
    GetIfTable(tb)
    loop, % DecodeInteger(&tb)
    {
        dnNew += DecodeInteger(&tb + 4 + 860 * (A_Index - 1) + 552)
        upNew += DecodeInteger(&tb + 4 + 860 * (A_Index - 1) + 576)
    }
    dnRate := Round((dnNew - dnOld) / 1024)
    upRate := Round((upNew - upOld) / 1024)
    GuiControl,, In1, % dnRate " kb/s"
    GuiControl,, Ou1, % upRate " kb/s"
    dnOld := dnNew
    upOld := upNew
return

UpdateMemHtop:
    if (BuildVersion >= "7600")
    {
        GPMI := GetProcessMemoryInfo_PMCEX(ownPID)
        PUsage := Round(GPMI[10] / 1024, 0)
    }
    else
    {
        GPMI := GetProcessMemoryInfo_PMC(ownPID)
        PUsage := Round(GPMI[8] / 1024, 0)
    }
    GuiControl,, OwnMem, % "PID: " ownPID " | " PUsage " K"
    SetTimer, UpdateMemHtop, 2000
return

DriveClick:
    Run, % SubStr(A_GuiControl, 3)
Return

Clear:
    ClearMemory()
    FreeMemory()
return

Minimi:
    Gui, Hide
return

Menu_Percentage:
    varPerc := (varPerc = "0") ? "1" : "0"
    Menu, Tray, ToggleCheck, Toggle Percentage
return

Menu_Transparency:
    WinSet, Transparent, 170, % name
return

Menu_AlwaysOnTop:
    WinSet, AlwaysOnTop, Toggle, %WinTitel%
    Menu, Tray, ToggleCheck, Toggle AlwaysOnTop
return

Menu_ShowHide:
    WinGet, winStyle, Style, %WinTitel%
    if (winStyle & 0x10000000)
    {
        WinHide, %WinTitel%
    }
    else
    {
        WinShow, %WinTitel%
        WinSet, AlwaysOnTop, Toggle, %WinTitel%
        WinSet, AlwaysOnTop, Toggle, %WinTitel%
    }
return

^WheelUp::GUITrans(1)
^WheelDown::GUITrans(0)


; ###################################################################################
; ### FUNCTIONS                                                                   ###
; ###################################################################################

WM_LBUTTONDOWN(wParam, lParam, msg, hwnd)
{
    global hMain
    if (hwnd = hMain)
    {
        PostMessage, 0xA1, 2,,, % WinTitel
    }
}

WM_DEVICECHANGE(wParam, lParam, msg, hwnd)
{
    global hmain, htopx, htopy
    if (wParam = 0x8000 || wParam = 0x8004)
    {
        Thread, NoTimers
        WinGetPos, htopx, htopy,,, ahk_id %hmain%
        Gui, Destroy
        Gosub, MakeGui
    }
}

; GUITrans ==========================================================================
GUITrans(b := 1)
{
    WinGet, ct, Transparent, % WinTitel
    WinSet, Transparent, % ((b = 1) ? ct + 1 : ct - 1), % WinTitel
}

; DownloadToString ==================================================================
DownloadToString(url, encoding := "utf-8")
{
    static a := "AutoHotkey/" A_AhkVersion
    if (!DllCall("LoadLibrary", "Str", "wininet") || !(h := DllCall("wininet\InternetOpen", "Str", a, "UInt", 1, "Ptr", 0, "Ptr", 0, "UInt", 0, "Ptr")))
    {
        return 0
    }
    c := s := 0, o := ""
    if (f := DllCall("wininet\InternetOpenUrl", "Ptr", h, "Str", url, "Ptr", 0, "UInt", 0, "UInt", 0x80003000, "Ptr", 0, "Ptr"))
    {
        while (DllCall("wininet\InternetQueryDataAvailable", "Ptr", f, "UInt*", s, "UInt", 0, "Ptr", 0) && s > 0)
        {
            VarSetCapacity(b, s, 0)
            DllCall("wininet\InternetReadFile", "Ptr", f, "Ptr", &b, "UInt", s, "UInt*", r)
            o .= StrGet(&b, r >> (encoding = "utf-16" || encoding = "cp1200"), encoding)
        }
        DllCall("wininet\InternetCloseHandle", "Ptr", f)
    }
    DllCall("wininet\InternetCloseHandle", "Ptr", h)
    return o
}

; ProcessCount ======================================================================
GetProcessCount()
{
    proc := ""
    for process in ComObjGet("winmgmts:\\.\root\CIMV2").ExecQuery("SELECT * FROM Win32_Process")
    {
        proc++
    }
    return proc
}

; CPULoad ===========================================================================
CPULoad()
{
    static PIT, PKT, PUT
    if (Pit = "")
    {
        return 0, DllCall("GetSystemTimes", "Int64P", PIT, "Int64P", PKT, "Int64P", PUT)
    }
    DllCall("GetSystemTimes", "Int64P", CIT, "Int64P", CKT, "Int64P", CUT)
    IdleTime := PIT - CIT, KernelTime := PKT - CKT, UserTime := PUT - CUT
    SystemTime := KernelTime + UserTime 
    return ((SystemTime - IdleTime) * 100) // SystemTime, PIT := CIT, PKT := CKT, PUT := CUT 
}

; GlobalMemoryStatus ================================================================
GlobalMemoryStatusEx()
{
    static MEMORYSTATUSEX, init := VarSetCapacity(MEMORYSTATUSEX, 64, 0) && NumPut(64, MEMORYSTATUSEX, "UInt")
    if (DllCall("Kernel32.dll\GlobalMemoryStatusEx", "Ptr", &MEMORYSTATUSEX))
    {
        return { 2 : NumGet(MEMORYSTATUSEX,  8, "UInt64")
               , 3 : NumGet(MEMORYSTATUSEX, 16, "UInt64")
               , 4 : NumGet(MEMORYSTATUSEX, 24, "UInt64")
               , 5 : NumGet(MEMORYSTATUSEX, 32, "UInt64") }
    }
}

; GetProcessMemoryInfo ==============================================================
GetProcessMemoryInfo_PMCEX(PID)
{
    pu := ""
    hProcess := DllCall("Kernel32.dll\OpenProcess", "UInt", 0x001F0FFF, "UInt", 0, "UInt", PID)
    if (hProcess)
    {
        static PMCEX, size := (A_PtrSize = 8 ? 80 : 44), init := VarSetCapacity(PMCEX, size, 0) && NumPut(size, PMCEX)
        if (DllCall("Kernel32.dll\K32GetProcessMemoryInfo", "Ptr", hProcess, "UInt", &PMCEX, "UInt", size))
        {
            pu := { 10 : NumGet(PMCEX, (A_PtrSize = 8 ? 72 : 40), "Ptr") }
        }
        DllCall("Kernel32.dll\CloseHandle", "Ptr", hProcess)
    }
    return pu
}
GetProcessMemoryInfo_PMC(PID)
{
    pu := ""
    hProcess := DllCall("Kernel32.dll\OpenProcess", "UInt", 0x001F0FFF, "UInt", 0, "UInt", PID)
    if (hProcess)
    {
        static PMC, size := (A_PtrSize = 8 ? 72 : 40), init := VarSetCapacity(PMC, size, 0) && NumPut(size, PMC)
        if (DllCall("psapi.dll\GetProcessMemoryInfo", "Ptr", hProcess, "UInt", &PMC, "UInt", size))
        {
            pu := { 8 : NumGet(PMC, (A_PtrSize = 8 ? 56 : 32), "Ptr") }
        }
        DllCall("Kernel32.dll\CloseHandle", "Ptr", hProcess)
    }
    return pu
}

; secsToStr =========================================================================
GetDurationFormat(ullDuration, lpFormat := "d'd 'hh:mm:ss")
{
    VarSetCapacity(lpDurationStr, 128, 0)
    DllCall("Kernel32.dll\GetDurationFormat", "UInt",  0x400
                                            , "UInt",  0
                                            , "Ptr",   0
                                            , "Int64", ullDuration * 10000000
                                            , "WStr",  lpFormat
                                            , "WStr",  lpDurationStr
                                            , "Int",   64)
    return lpDurationStr
}

; NetTraffic ========================================================================
GetIfTable(ByRef tb, bOrder = True)
{
    nSize := 4 + 860 * GetNumberOfInterfaces() + 8
    VarSetCapacity(tb, nSize)
    return DllCall("Iphlpapi.dll\GetIfTable", "UInt", &tb, "UInt*", nSize, "UInt", bOrder)
}
GetIfEntry(ByRef tb, idx)
{
    VarSetCapacity(tb, 860)
    DllCall("ntdll\RtlFillMemoryUlong", "Ptr", &tb + 512, "Ptr", 4, "UInt", idx)
    return DllCall("Iphlpapi.dll\GetIfEntry", "UInt", &tb)
}
GetNumberOfInterfaces()
{
    DllCall("Iphlpapi.dll\GetNumberOfInterfaces", "UInt*", nIf)
    return nIf
}
DecodeInteger(ptr)
{
    return *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24
}

; ClearMemory =======================================================================
ClearMemory()
{
    for process in ComObjGet("winmgmts:\\.\root\CIMV2").ExecQuery("SELECT * FROM Win32_Process")
    {
        handle := DllCall("Kernel32.dll\OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", process.ProcessID)
        DllCall("Kernel32.dll\SetProcessWorkingSetSize", "UInt", handle, "Int", -1, "Int", -1)
        DllCall("Psapi.dll\EmptyWorkingSet", "UInt", handle)
        DllCall("Kernel32.dll\CloseHandle", "Int", handle)
    }
    return
}
FreeMemory()
{
    return DllCall("Psapi.dll\EmptyWorkingSet", "UInt", -1)
}


; ###################################################################################
; ### EXIT                                                                        ###
; ###################################################################################

Close:
GuiClose:
GuiEscape:
    ExitApp


Bruttosozialprodukt
  • Members
  • 457 posts
  • Last active: Oct 18 2015 08:47 AM
  • Joined: 20 Oct 2012

Same issue. It shows way too much load (eg 18% when it's actually 8%), also it only shows the usage of all processes together.



Bruttosozialprodukt
  • Members
  • 457 posts
  • Last active: Oct 18 2015 08:47 AM
  • Joined: 20 Oct 2012

No one?



RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

The function in the original post cannot be called for multiple processes, as it calculates the usage based on saved data (specific to that process) from the last call. I could be missing something here, but I believe the function has a major limitation. Since it measures the process CPU usage against the maximum possible process usage for a hard coded period of time, then the function must be called using this specific interval so as to maintain accuracy. However, when I calculate this required period the results do not match the windows task manager output.....so I guess I'm doing something wrong.

 

I just wrote this and it seems to reflect the results of the task manager on a multi-core system. It saves the data for each pid in an array, so you can call it for different processes like you were doing.

#singleinstance force 

Gui, Add, ListView, x2 y0 w400 h500, Name|PID|CPU
for process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
    LV_Add("", process.Name, process.processId,"...")
Gui, Show,, Process List

SetTimer, UpdateCpuUsage
Return

UpdateCpuUsage:
    Loop % LV_GetCount() {
        LV_GetText(pid, A_Index, 2)
        cpuUsage := Round(GetProcessTimes(pid)) "%"
        LV_Modify(A_Index, "Col3", cpuUsage)
    }
Return

; Return values
; -1 on first run 
; -2 if process doesn't exist or you don't have access to it
; Process cpu usage as percent of total CPU
GetProcessTimes(PID)    
{
    static aPIDs := []
    ; If called too frequently, will get mostly 0%, so it's better to just return the previous usage 
    if aPIDs.HasKey(PID) && A_TickCount - aPIDs[PID, "tickPrior"] < 250
        return aPIDs[PID, "usagePrior"] 

    DllCall("GetSystemTimes", "Int64*", lpIdleTimeSystem, "Int64*", lpKernelTimeSystem, "Int64*", lpUserTimeSystem)
    if !hProc := DllCall("OpenProcess", "UInt", 0x400, "Int", 0, "Ptr", pid)
        return -2, aPIDs.HasKey(PID) ? aPIDs.Remove(PID, "") : "" ; Process doesn't exist anymore or don't have access to it.
    DllCall("GetProcessTimes", "Ptr", hProc, "Int64*", lpCreationTime, "Int64*", lpExitTime, "Int64*", lpKernelTimeProcess, "Int64*", lpUserTimeProcess)
    DllCall("CloseHandle", "Ptr", hProc)
    
    if aPIDs.HasKey(PID) ; check if previously run
    {
        ; find the total system run time delta between the two calls
        systemKernelDelta := lpKernelTimeSystem - aPIDs[PID, "lpKernelTimeSystem"] ;lpKernelTimeSystemOld
        systemUserDelta := lpUserTimeSystem - aPIDs[PID, "lpUserTimeSystem"] ; lpUserTimeSystemOld
        ; get the total process run time delta between the two calls 
        procKernalDelta := lpKernelTimeProcess - aPIDs[PID, "lpKernelTimeProcess"] ; lpKernelTimeProcessOld
        procUserDelta := lpUserTimeProcess - aPIDs[PID, "lpUserTimeProcess"] ;lpUserTimeProcessOld
        ; sum the kernal + user time
        totalSystem :=  systemKernelDelta + systemUserDelta
        totalProcess := procKernalDelta + procUserDelta
        ; The result is simply the process delta run time as a percent of system delta run time
        result := 100 * totalProcess / totalSystem
    }
    else result := -1

    aPIDs[PID, "lpKernelTimeSystem"] := lpKernelTimeSystem
    aPIDs[PID, "lpUserTimeSystem"] := lpUserTimeSystem
    aPIDs[PID, "lpKernelTimeProcess"] := lpKernelTimeProcess
    aPIDs[PID, "lpUserTimeProcess"] := lpUserTimeProcess
    aPIDs[PID, "tickPrior"] := A_TickCount
    return aPIDs[PID, "usagePrior"] := result 
}


jNizM
  • Members
  • 928 posts
  • Last active: Jan 12 2018 09:23 AM
  • Joined: 01 Aug 2012
hmmm...
J7SEhXq.jpg
"-2 if process doesn't exist or you don't have access to it"

Everytime -2? Is it not possible to get the info?
[AHK] 1.1.27.04 x64 Unicode | [WIN] 10 Pro (Version 1709)
My GitHub Profile | Donations are appreciated if I could help you

Bruttosozialprodukt
  • Members
  • 457 posts
  • Last active: Oct 18 2015 08:47 AM
  • Joined: 20 Oct 2012

@RHCP That looks pretty good. But it shows -2% for almost every system and service process, even if I run it as admin. :/



Bruttosozialprodukt
  • Members
  • 457 posts
  • Last active: Oct 18 2015 08:47 AM
  • Joined: 20 Oct 2012

Do we need to enable debug privileges or something to get access to the other processes?



RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

It probably is. The previous posted function also had this issue, although it would have returned 0, so you probably didn't realise. I will have a look later.

 

Cheers.



Bruttosozialprodukt
  • Members
  • 457 posts
  • Last active: Oct 18 2015 08:47 AM
  • Joined: 20 Oct 2012

So I tired to set debug privileges in the beginning of the script:

DllCall("advapi32.dll\LookupPrivilegeValueA","UInt",0,"Str","SeDebugPrivilege","Int64*",luid)

and added PROCESS_ALL_ACCESS (0x1F0FFF) to OpenProcess:

DllCall("OpenProcess", "UInt", 0x400|0x1F0FFF, "Int", 0, "Ptr", pid)

but it's still not working (same issue).

 

edit:

I also tried it with SeProfileSingleProcessPrivilege (not sure what it does really), but it's still not working...



RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

You need to run the script as admin. 

 

Simply opening the process handle (in GetProcessTimes) with PROCESS_QUERY_LIMITED_INFORMATION access will work for most of the processes.

You can get a couple more (but not all) by using setSeDebugPrivilege.

 

To enable SeDebugPrivilege call this function once. (This was copied from the AHK manual - process command page. I just added a disable option)

setSeDebugPrivilege(enable := True)
{
    h := DllCall("OpenProcess", "UInt", 0x0400, "Int", false, "UInt", DllCall("GetCurrentProcessId"), "Ptr")
    ; Open an adjustable access token with this process (TOKEN_ADJUST_PRIVILEGES = 32)
    DllCall("Advapi32.dll\OpenProcessToken", "Ptr", h, "UInt", 32, "PtrP", t)
    VarSetCapacity(ti, 16, 0)  ; structure of privileges
    NumPut(1, ti, 0, "UInt")  ; one entry in the privileges array...
    ; Retrieves the locally unique identifier of the debug privilege:
    DllCall("Advapi32.dll\LookupPrivilegeValue", "Ptr", 0, "Str", "SeDebugPrivilege", "Int64P", luid)
    NumPut(luid, ti, 4, "Int64")
    if enable
    	NumPut(2, ti, 12, "UInt")  ; enable this privilege: SE_PRIVILEGE_ENABLED = 2
    ; Update the privileges of this process with the new access token:
    r := DllCall("Advapi32.dll\AdjustTokenPrivileges", "Ptr", t, "Int", false, "Ptr", &ti, "UInt", 0, "Ptr", 0, "Ptr", 0)
    DllCall("CloseHandle", "Ptr", t)  ; close this access token handle to save memory
    DllCall("CloseHandle", "Ptr", h)  ; close this process handle to save memory
    return r
}

And here's GetProcessTimes using PROCESS_QUERY_LIMITED_INFORMATION 

; Return values
; -1 on first run 
; -2 if process doesn't exist or you don't have access to it
; Process cpu usage as percent of total CPU
getProcessTimes(PID)    
{
    static aPIDs := [], hasSetDebug
    ; If called too frequently, will get mostly 0%, so it's better to just return the previous usage 
    if aPIDs.HasKey(PID) && A_TickCount - aPIDs[PID, "tickPrior"] < 250
        return aPIDs[PID, "usagePrior"] 
   	; Open a handle with PROCESS_QUERY_LIMITED_INFORMATION access
    if !hProc := DllCall("OpenProcess", "UInt", 0x1000, "Int", 0, "Ptr", pid, "Ptr")
        return -2, aPIDs.HasKey(PID) ? aPIDs.Remove(PID, "") : "" ; Process doesn't exist anymore or don't have access to it.
         
    DllCall("GetProcessTimes", "Ptr", hProc, "Int64*", lpCreationTime, "Int64*", lpExitTime, "Int64*", lpKernelTimeProcess, "Int64*", lpUserTimeProcess)
    DllCall("CloseHandle", "Ptr", hProc)
    DllCall("GetSystemTimes", "Int64*", lpIdleTimeSystem, "Int64*", lpKernelTimeSystem, "Int64*", lpUserTimeSystem)
   
    if aPIDs.HasKey(PID) ; check if previously run
    {
        ; find the total system run time delta between the two calls
        systemKernelDelta := lpKernelTimeSystem - aPIDs[PID, "lpKernelTimeSystem"] ;lpKernelTimeSystemOld
        systemUserDelta := lpUserTimeSystem - aPIDs[PID, "lpUserTimeSystem"] ; lpUserTimeSystemOld
        ; get the total process run time delta between the two calls 
        procKernalDelta := lpKernelTimeProcess - aPIDs[PID, "lpKernelTimeProcess"] ; lpKernelTimeProcessOld
        procUserDelta := lpUserTimeProcess - aPIDs[PID, "lpUserTimeProcess"] ;lpUserTimeProcessOld
        ; sum the kernal + user time
        totalSystem :=  systemKernelDelta + systemUserDelta
        totalProcess := procKernalDelta + procUserDelta
        ; The result is simply the process delta run time as a percent of system delta run time
        result := 100 * totalProcess / totalSystem
    }
    else result := -1

    aPIDs[PID, "lpKernelTimeSystem"] := lpKernelTimeSystem
    aPIDs[PID, "lpKernelTimeSystem"] := lpKernelTimeSystem
    aPIDs[PID, "lpUserTimeSystem"] := lpUserTimeSystem
    aPIDs[PID, "lpKernelTimeProcess"] := lpKernelTimeProcess
    aPIDs[PID, "lpUserTimeProcess"] := lpUserTimeProcess
    aPIDs[PID, "tickPrior"] := A_TickCount
    return aPIDs[PID, "usagePrior"] := result 
}

I'm just a scripter, so don't take my word for any of this.



Bruttosozialprodukt
  • Members
  • 457 posts
  • Last active: Oct 18 2015 08:47 AM
  • Joined: 20 Oct 2012

Nice! For me it now returned a value for every process (but the System Idle process). Maybe because I ran it as admin?

I also put:

    if (!pid) {
        For k, v in aPIDs
            idle += aPIDs[k, "usagePrior"]
        return 100-idle
    }

in the very beginning of the getProcessTimes function so that it returns the system idle processes value. (I hope I did it right, it seems to work though)



RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

Nice! For me it now returned a value for every process (but the System Idle process). Maybe because I ran it as admin?

 

With regards to it working for most processes, it may depend on the desiredAccess parameter in the openProcess() call in getProcessTimes(). When I ran the script as admin and used PROCESS_QUERY_INFORMATION (0x400) most of the system processes gave -2. However if the script is ran as admin and PROCESS_QUERY_LIMITED_INFORMATION (0x1000) is used, it will work with most of the system processes. In my last post the function used PROCESS_QUERY_LIMITED_INFORMATION.

 

If you reload a script which has SeDebugPrivilege enabled, then the new instance of the script will inherit this change. This could lead to false results when testing the effect of SeDebugPrivilege.

 

 

Regardless of access level/rights, I don't believe you can open a handle to 'system idle process' using OpenProcess(). That is a nice substitute.

 

Cheers.