• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 497
  • Last Modified:

CPU Usage of process

Is there a quick and simple way to query the current CPU usage of a process, i would prefer to have a simple function and not a component.

thanks.
0
heretoread
Asked:
heretoread
  • 2
1 Solution
 
sun4sundayCommented:
0
 
sun4sundayCommented:
Copying the Madshi code below

function GetProcessorTime : int64;
type
  TPerfDataBlock = packed record
    signature              : array [0..3] of wchar;
    littleEndian           : cardinal;
    version                : cardinal;
    revision               : cardinal;
    totalByteLength        : cardinal;
    headerLength           : cardinal;
    numObjectTypes         : integer;
    defaultObject          : cardinal;
    systemTime             : TSystemTime;
    perfTime               : comp;
    perfFreq               : comp;
    perfTime100nSec        : comp;
    systemNameLength       : cardinal;
    systemnameOffset       : cardinal;
  end;
  TPerfObjectType = packed record
    totalByteLength        : cardinal;
    definitionLength       : cardinal;
    headerLength           : cardinal;
    objectNameTitleIndex   : cardinal;
    objectNameTitle        : PWideChar;
    objectHelpTitleIndex   : cardinal;
    objectHelpTitle        : PWideChar;
    detailLevel            : cardinal;
    numCounters            : integer;
    defaultCounter         : integer;
    numInstances           : integer;
    codePage               : cardinal;
    perfTime               : comp;
    perfFreq               : comp;
  end;
  TPerfCounterDefinition = packed record
    byteLength             : cardinal;
    counterNameTitleIndex  : cardinal;
    counterNameTitle       : PWideChar;
    counterHelpTitleIndex  : cardinal;
    counterHelpTitle       : PWideChar;
    defaultScale           : integer;
    defaultLevel           : cardinal;
    counterType            : cardinal;
    counterSize            : cardinal;
    counterOffset          : cardinal;
  end;
  TPerfInstanceDefinition = packed record
    byteLength             : cardinal;
    parentObjectTitleIndex : cardinal;
    parentObjectInstance   : cardinal;
    uniqueID               : integer;
    nameOffset             : cardinal;
    nameLength             : cardinal;
  end;
var  c1, c2, c3      : cardinal;
     i1, i2          : integer;
     perfDataBlock   : ^TPerfDataBlock;
     perfObjectType  : ^TPerfObjectType;
     perfCounterDef  : ^TPerfCounterDefinition;
     perfInstanceDef : ^TPerfInstanceDefinition;
begin
  result := 0;
  perfDataBlock := nil;
  try
    c1 := $10000;
    while true do begin
      ReallocMem(perfDataBlock, c1);
      c2 := c1;
      case RegQueryValueEx(HKEY_PERFORMANCE_DATA, '238', nil, @c3, pointer(perfDataBlock), @c2) of
        ERROR_MORE_DATA : c1 := c1 * 2;
        ERROR_SUCCESS   : break;
        else              exit;
      end;
    end;
    perfObjectType := pointer(cardinal(perfDataBlock) + perfDataBlock^.headerLength);
    for i1 := 0 to perfDataBlock^.numObjectTypes - 1 do begin
      if perfObjectType^.objectNameTitleIndex = 238 then begin   // 238 -> "Processor"
        perfCounterDef := pointer(cardinal(perfObjectType) + perfObjectType^.headerLength);
        for i2 := 0 to perfObjectType^.numCounters - 1 do begin
          if perfCounterDef^.counterNameTitleIndex = 6 then begin    // 6 -> "% Processor Time"
            perfInstanceDef := pointer(cardinal(perfObjectType) + perfObjectType^.definitionLength);
            result := PInt64(cardinal(perfInstanceDef) + perfInstanceDef^.byteLength + perfCounterDef^.counterOffset)^;
            break;
          end;
          inc(perfCounterDef);
        end;
        break;
      end;
      perfObjectType := pointer(cardinal(perfObjectType) + perfObjectType^.totalByteLength);
    end;
  finally FreeMem(perfDataBlock) end;
end;
 
var LastTickCount     : cardinal = 0;
    LastProcessorTime : int64    = 0;
function GetProcessorUsage : integer;
var tickCount     : cardinal;
    processorTime : int64;
begin
  result := 0;
  tickCount     := GetTickCount;
  processorTime := GetProcessorTime;
  if (LastTickCount <> 0) and (tickCount <> LastTickCount) then
    result := 100 - Round(((processorTime - LastProcessorTime) div 100) / (tickCount - LastTickCount));
  LastTickCount     := tickCount;
  LastProcessorTime := processorTime;
end;

GetProcessorUsage gives you the overall CPU utilization in percent.

sun4sunday
0
 
dublicatorCommented:
unit Unit1;

interface

uses
  registry, Windows, SysUtils, Forms, Gauges, Classes, Controls, ExtCtrls,
    StdCtrls;

type
  TForm1 = class(TForm)
    Gauge1: TGauge;
    Timer1: TTimer;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  def: string;
  reg: TRegistry;
  Buffer: array[0..1000] of integer;
begin
  //-------------------------------
  reg := TRegistry.Create;
  reg.RootKey := HKEY_DYN_DATA;
  def := '';
  if reg.OpenKey('PerfStats\StartStat', false) = TRUE then
  begin
    reg.ReadBinaryData('KERNEL\CPUusage', buffer, 1000);
  end;
  reg.CloseKey;
  Timer1.Enabled := true;

end;
//-------------------------------

procedure TForm1.Timer1Timer(Sender: TObject);
var
  def: string;
  reg: TRegistry;
  B: array[1..4] of integer;
begin
  reg := TRegistry.Create;
  reg.RootKey := HKEY_DYN_DATA;
  def := '';
  if reg.OpenKey('PerfStats\StatData', false) = TRUE then
  begin
    reg.ReadBinaryData('KERNEL\CPUusage', b, 4);
  end;

  reg.CloseKey;
  Gauge1.Progress := b[1];
  Application.ProcessMessages;

  //-------------------------------
end;

end.



or



only for NT/2000/XP:
const
  SystemBasicInformation = 0;
  SystemPerformanceInformation = 2;
  SystemTimeInformation = 3;

type
  TPDWord = ^DWORD;

  TSystem_Basic_Information = packed record
    dwUnknown1: DWORD;
    uKeMaximumIncrement: ULONG;
    uPageSize: ULONG;
    uMmNumberOfPhysicalPages: ULONG;
    uMmLowestPhysicalPage: ULONG;
    uMmHighestPhysicalPage: ULONG;
    uAllocationGranularity: ULONG;
    pLowestUserAddress: Pointer;
    pMmHighestUserAddress: Pointer;
    uKeActiveProcessors: ULONG;
    bKeNumberProcessors: byte;
    bUnknown2: byte;
    wUnknown3: word;
  end;

type
  TSystem_Performance_Information = packed record
    liIdleTime: LARGE_INTEGER; {LARGE_INTEGER}
    dwSpare: array[0..75] of DWORD;
  end;

type
  TSystem_Time_Information = packed record
    liKeBootTime: LARGE_INTEGER;
    liKeSystemTime: LARGE_INTEGER;
    liExpTimeZoneBias: LARGE_INTEGER;
    uCurrentTimeZoneId: ULONG;
    dwReserved: DWORD;
  end;

var
  NtQuerySystemInformation: function(infoClass: DWORD;
    buffer: Pointer;
    bufSize: DWORD;
    returnSize: TPDword): DWORD; stdcall = nil;

  liOldIdleTime: LARGE_INTEGER = ();
  liOldSystemTime: LARGE_INTEGER = ();

function Li2Double(x: LARGE_INTEGER): Double;
begin
  Result := x.HighPart * 4.294967296E9 + x.LowPart
end;

procedure GetCPUUsage;
var
  SysBaseInfo: TSystem_Basic_Information;
  SysPerfInfo: TSystem_Performance_Information;
  SysTimeInfo: TSystem_Time_Information;
  status: Longint; {long}
  dbSystemTime: Double;
  dbIdleTime: Double;

  bLoopAborted: boolean;

begin
  if @NtQuerySystemInformation = nil then
    NtQuerySystemInformation := GetProcAddress(GetModuleHandle('ntdll.dll'),
      'NtQuerySystemInformation');

  // get number of processors in the system

  status := NtQuerySystemInformation(SystemBasicInformation, @SysBaseInfo,
    SizeOf(SysBaseInfo), nil);
  if status <> 0 then
    Exit;

  // Show some information
  with SysBaseInfo do
  begin
    ShowMessage(
      Format('uKeMaximumIncrement: %d'#13'uPageSize: %d'#13   +
      'uMmNumberOfPhysicalPages: %d' + #13 + 'uMmLowestPhysicalPage: %d' + #13 +
      'uMmHighestPhysicalPage: %d' + #13 + 'uAllocationGranularity: %d'#13 +
      'uKeActiveProcessors: %d'#13'bKeNumberProcessors: %d'  ,
      [uKeMaximumIncrement, uPageSize, uMmNumberOfPhysicalPages,
      uMmLowestPhysicalPage, uMmHighestPhysicalPage, uAllocationGranularity,
        uKeActiveProcessors, bKeNumberProcessors]));
  end;

  bLoopAborted := False;

  while not bLoopAborted do
  begin

    // get new system time
    status := NtQuerySystemInformation(SystemTimeInformation, @SysTimeInfo,
      SizeOf(SysTimeInfo), 0);
    if status <> 0 then
      Exit;

    // get new CPU's idle time
    status := NtQuerySystemInformation(SystemPerformanceInformation,
      @SysPerfInfo, SizeOf(SysPerfInfo), nil);
    if status <> 0 then
      Exit;

    // if it's a first call - skip it
    if (liOldIdleTime.QuadPart <> 0) then
    begin

      // CurrentValue = NewValue - OldValue
      dbIdleTime := Li2Double(SysPerfInfo.liIdleTime) -
        Li2Double(liOldIdleTime);
      dbSystemTime := Li2Double(SysTimeInfo.liKeSystemTime) -
        Li2Double(liOldSystemTime);

      // CurrentCpuIdle = IdleTime / SystemTime
      dbIdleTime := dbIdleTime / dbSystemTime;

      // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
      dbIdleTime := 100.0 - dbIdleTime * 100.0 / SysBaseInfo.bKeNumberProcessors
        + 0.5;

      // Show Percentage
      Form1.Label1.Caption := FormatFloat('CPU Usage: 0.0 %', dbIdleTime);

      Application.ProcessMessages;

      // Abort if user pressed ESC or Application is terminated
      bLoopAborted := (GetKeyState(VK_ESCAPE) and 128 = 128) or
        Application.Terminated;

    end;

    // store new CPU's idle and system time
    liOldIdleTime := SysPerfInfo.liIdleTime;
    liOldSystemTime := SysTimeInfo.liKeSystemTime;

    // wait one second
    Sleep(1000);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  GetCPUUsage
end;
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now