procedure TForm1.Button1Click(Sender: TObject); var Dummy : array[0..1024] of byte;
begin Reg:=TRegistry.Create; Reg.RootKey:=HKEY_DYN_DATA; //统计数据在这个表项下 Reg.OpenKey('PerfStats\StartStat',false); // Reg.ReadBinaryData('KERNEL\CPUUsage',Dummy,Sizeof(Dummy)); Reg.CloseKey; started:=true; end;
procedure TForm1.Timer1Timer(Sender: TObject); var CPUU : integer;
begin if started then begin Reg.OpenKey('PerfStats\StatData',false); Reg.ReadBinaryData('KERNEL\CPUUsage',CPUU,SizeOf(Integer)); Reg.CloseKey; Label1.Caption:=IntToStr(CPUU)+'%'; end; end;
procedure TForm1.Button2Click(Sender: TObject); var Dummy : array[0..1024] of byte;
begin 'PerfStats/StopStat' } Reg.OpenKey('PerfStats\StopStat',false); Reg.ReadBinaryData('KERNEL\CPUUsage',Dummy,SizeOf(Dummy)); Reg.Free; Started:=false; end;
Author: Alexey A. Dynnikov EMail: aldyn@chat.ru WebSite: http://www.aldyn.ru/ Support: Use the e-mail aldyn@chat.ru or support@aldyn.ru
Creation: Jul 8, 2000 Version: 1.02
Legal issues: Copyright (C) 2000 by Alexey A. Dynnikov <aldyn@chat.ru>
This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented, you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
2. Call GetCPUCount to obtain the numbr of processors in the system
3. Each time you need to know the value of CPU usage call the CollectCPUData to refresh the CPU usage information. Then call the GetCPUUsage to obtain the CPU usage for given processor. Note that succesive calls of GetCPUUsage without calling CollectCPUData will return the same CPU usage value.
Example:
procedure TTestForm.TimerTimer(Sender: TObject); var i: Integer; begin CollectCPUData; // Get the data for all processors
for i:=0 to GetCPUCount-1 do // Show data for each processor MInfo.Lines[i]:=Format('CPU #%d - %5.2f%%',[i,GetCPUUsage(i)*100]); end; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
interface
uses Windows, SysUtils;
// Call CollectCPUData to refresh information about CPU usage procedure CollectCPUData;
// Call it to obtain the number of CPU's in the system function GetCPUCount: Integer;
// Call it to obtain the % of usage for given CPU function GetCPUUsage(Index: Integer): Double;
// For Win9x only: call it to stop CPU usage monitoring and free system resources procedure ReleaseCPUData;
//------------------------------------------------------------------------------ {$ifdef ver130} {$L-} // The L+ causes internal error in Delphi 5 compiler {$O-} // The O+ causes internal error in Delphi 5 compiler {$Y-} // The Y+ causes internal error in Delphi 5 compiler {$endif}
{$ifndef ver110} type TInt64F = TInt64; {$else} type TInt64F = Extended; {$endif}
{$ifdef ver110} function FInt64(Value: TInt64): TInt64F; function Int64D(Value: DWORD): TInt64; {$else} type FInt64 = TInt64F; Int64D = TInt64; {$endif}
{$ifdef ver110} function FInt64(Value: TInt64): TInt64F; var V: TInt64; begin if (Value.HighPart and $80000000) = 0 then // positive value begin result:=Value.HighPart; result:=result*$10000*$10000; result:=result+Value.LowPart; end else begin V.HighPart:=Value.HighPart xor $FFFFFFFF; V.LowPart:=Value.LowPart xor $FFFFFFFF; result:= -1 - FInt64(V); end; end;
function Int64D(Value: DWORD): TInt64; begin result.LowPart:=Value; result.HighPart := 0; // positive only end; {$endif}
//------------------------------------------------------------------------------ function GetCPUCount: Integer; begin if _IsWinNT then begin if _ProcessorsCount < 0 then CollectCPUData; result:=_ProcessorsCount; end else begin result:=1; end;
end;
//------------------------------------------------------------------------------ procedure ReleaseCPUData; var H: HKEY; R: DWORD; dwDataSize, dwType: DWORD; begin if _IsWinNT then exit; if not _W9xCollecting then exit; _W9xCollecting:=False;
RegCloseKey(_W9xCpuKey);
R:=RegOpenKeyEx( HKEY_DYN_DATA, 'PerfStats\StopStat', 0, KEY_ALL_ACCESS, H );
//------------------------------------------------------------------------------ function GetCPUUsage(Index: Integer): Double; begin if _IsWinNT then begin if _ProcessorsCount < 0 then CollectCPUData; if (Index >= _ProcessorsCount) or (Index < 0) then raise Exception.Create('CPU index out of bounds'); if _PrevSysTime = _SysTime then result:=0 else result:=1-(_Counters[index] - _PrevCounters[index])/(_SysTime-_PrevSysTime); end else begin if Index <> 0 then raise Exception.Create('CPU index out of bounds'); if not _W9xCollecting then CollectCPUData; result:=_W9xCpuUsage / 100; end; end;
var H: HKEY; R: DWORD; dwDataSize, dwType: DWORD; begin if _IsWinNT then begin BS:=_BufferSize; while RegQueryValueEx( HKEY_PERFORMANCE_DATA, Processor_IDX_Str, nil, nil, PByte(_PerfData), @BS ) = ERROR_MORE_DATA do begin // Get a buffer that is big enough. INC(_BufferSize,$1000); BS:=_BufferSize; ReallocMem( _PerfData, _BufferSize ); end;
// Locate the performance object _POT := PPERF_OBJECT_TYPE(DWORD(_PerfData) + _PerfData.HeaderLength); for i := 1 to _PerfData.NumObjectTypes do begin if _POT.ObjectNameTitleIndex = Processor_IDX then Break; _POT := PPERF_OBJECT_TYPE(DWORD(_POT) + _POT.TotalByteLength); end;
// Check for success if _POT.ObjectNameTitleIndex <> Processor_IDX then raise Exception.Create('Unable to locate the "Processor" performance object');
if _ProcessorsCount < 0 then begin _ProcessorsCount:=_POT.NumInstances; GetMem(_Counters,_ProcessorsCount*SizeOf(TInt64)); GetMem(_PrevCounters,_ProcessorsCount*SizeOf(TInt64)); end;
// Locate the "% CPU usage" counter definition _PCD := PPERF_Counter_DEFINITION(DWORD(_POT) + _POT.HeaderLength); for i := 1 to _POT.NumCounters do begin if _PCD.CounterNameTitleIndex = CPUUsageIDX then break; _PCD := PPERF_COUNTER_DEFINITION(DWORD(_PCD) + _PCD.ByteLength); end;
// Check for success if _PCD.CounterNameTitleIndex <> CPUUsageIDX then raise Exception.Create('Unable to locate the "% of CPU usage" performance counter');
// Collecting coutners _PID_Instance := PPERF_INSTANCE_DEFINITION(DWORD(_POT) + _POT.DefinitionLength); for i := 0 to _ProcessorsCount-1 do begin _PCB_Instance := PPERF_COUNTER_BLOCK(DWORD(_PID_Instance) + _PID_Instance.ByteLength );
_PrevSysTime:=_SysTime; SystemTimeToFileTime(_PerfData.SystemTime, ST); _SysTime:=FInt64(TInt64(ST)); end else begin if not _W9xCollecting then begin R:=RegOpenKeyEx( HKEY_DYN_DATA, 'PerfStats\StartStat', 0, KEY_ALL_ACCESS, H ); if R <> ERROR_SUCCESS then raise Exception.Create('Unable to start performance monitoring');