...get the CPU usage in percent on Windows NT/2000/XP?
Author: Thomas Stutz
Homepage: http://www.swissdelphicenter.ch
0 Comments to this tip [Write new comment]
[ Print tip ]
Tip Rating (14):
Skill:
Useful:
Overall:
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;
// See also AdCpuUsage (for 95/98/NT/2000/XP)