How to get instant CPU usage % of my app process

Viewed 130

I need to get the cpu usage in % of my own app process at the moment, exactly as the value shown by the column 'CPU' in Windows Task Manager, but using Delphi 11. Is this possible ?

I've found some examples in SO, but all of them gets the global cpu usage, not a specific process.

enter image description here

1 Answers

Here is a function that gets as input the process id (of any process), and gives as output the cpu percentage of this process.

//A function that returns CPU usage (in percent) for a given process id
function GetCpuUsage(PID:cardinal):single;
const
    cWaitTime=750;
var
    h: Cardinal;
    mCreationTime,mExitTime,mKernelTime, mUserTime: _FILETIME;
    TotalTime1,TotalTime2: Int64;
    SysInfo : _SYSTEM_INFO;
    CpuCount: Word;
begin
    //We need to know the number of CPUs and divide the result by that, otherwise we will get wrong percentage on multi-core systems
    GetSystemInfo(SysInfo);
    CpuCount := SysInfo.dwNumberOfProcessors;

    //We need to get a handle of the process with PROCESS_QUERY_INFORMATION privileges.
    h:=OpenProcess(PROCESS_QUERY_INFORMATION,false,PID);
    //We can use the GetProcessTimes() function to get the amount of time the process has spent in kernel mode and user mode.
    GetProcessTimes(h,mCreationTime,mExitTime,mKernelTime,mUserTime);
    TotalTime1:=int64(mKernelTime.dwLowDateTime or (mKernelTime.dwHighDateTime shr 32)) + int64(mUserTime.dwLowDateTime or (mUserTime.dwHighDateTime shr 32));

    //Wait a little
    Sleep(cWaitTime);

    GetProcessTimes(h,mCreationTime,mExitTime,mKernelTime,mUserTime);
    TotalTime2:=int64(mKernelTime.dwLowDateTime or (mKernelTime.dwHighDateTime shr 32))+
    int64(mUserTime.dwLowDateTime or (mUserTime.dwHighDateTime shr 32));

    //This should work out nicely, as there were approx. 250 ms between the calls
    //and the result will be a percentage between 0 and 100
    Result:=((TotalTime2-TotalTime1)/cWaitTime)/100/CpuCount;
    CloseHandle(h);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  pid: Word;
begin
  pid := GetCurrentProcessId;
  Button1.Caption := FormatFloat('0%', GetCpuUsage(pid));
end;

In a comment, op asks if there is a single command line to execute, to get the cpu percentage. Here is a solution for command line:

wmic /namespace:\\root\cimv2 path Win32_PerfFormattedData_PerfProc_Process WHERE "IDProcess = 5332" GET PercentProcessorTime

and

wmic /namespace:\\root\cimv2 path Win32_PerfFormattedData_PerfProc_Process WHERE "IDProcess = 5332" GET PercentUserTime

Where 5332 is the process ID.

But if you are going to use wmic to get the cpu percentage, then it is better to use it using WMI Objects from inside Delphi (using OLE Object).

Related