В случае это может быть полезно, вы также можете прочитать данные о производительности непосредственно. Вот простой пример, используя мой PerfUtils
и перевод winperf.h из JEDI API Library:
program test;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
JwaWinPerf,
PerfUtils in 'PerfUtils.pas';
const
CtrAvgDiskSecPerRead = 208;
procedure GetCounterAverageTimer(Obj: PPerfObjectType; NameIndex, InstanceIndex: Cardinal;
out TimerValue, BaseValue: Cardinal);
var
CounterTimer, CounterBase: PPerfCounterDefinition;
Instance: PPerfInstanceDefinition;
begin
TimerValue := 0;
BaseValue := 0;
// average timer counter
CounterTimer := GetCounterByNameIndex(Obj, NameIndex);
if not Assigned(CounterTimer) or (CounterTimer^.CounterType <> PERF_AVERAGE_TIMER) then
Exit;
// average base counter
CounterBase := GetNextCounter(CounterTimer);
if not Assigned(CounterBase) or (CounterBase^.CounterNameTitleIndex <> NameIndex) or
(CounterBase^.CounterType <> PERF_AVERAGE_BASE) then
Exit;
Instance := GetInstance(Obj, InstanceIndex);
if not Assigned(Instance) then
Exit;
TimerValue := GetCounterValue32(Obj, CounterTimer, Instance);
BaseValue := GetCounterValue32(Obj, CounterBase, Instance);
end;
function GetPhysicalDiskAvgSecPerRead(DiskInstance: Integer; Data1, Data2: PPerfDataBlock): Double;
var
Obj1, Obj2: PPerfObjectType;
TimerValue1, TimerValue2, BaseValue1, BaseValue2: Cardinal;
begin
Result := 0;
Obj1 := GetObjectByNameIndex(Data1, ObjPhysicalDisk);
Obj2 := GetObjectByNameIndex(Data2, ObjPhysicalDisk);
if not Assigned(Obj1) or not Assigned(Obj2) then
Exit;
GetCounterAverageTimer(Obj1, CtrAvgDiskSecPerRead, DiskInstance, TimerValue1, BaseValue1);
GetCounterAverageTimer(Obj2, CtrAvgDiskSecPerRead, DiskInstance, TimerValue2, BaseValue2);
if (TimerValue2 = TimerValue1) or (BaseValue2 = BaseValue1) then
Exit;
Result := (Int64(TimerValue2 - TimerValue1)/Data1^.PerfFreq.QuadPart)/Int64(BaseValue2 - BaseValue1);
end;
function GetDiskInstanceName(DiskInstance: Integer; Data: PPerfDataBlock): WideString;
var
Obj: PPerfObjectType;
Instance: PPerfInstanceDefinition;
begin
Result := '';
Obj := GetObjectByNameIndex(Data, ObjPhysicalDisk);
if not Assigned(Obj) then
Exit;
Instance := GetInstance(Obj, DiskInstance);
if not Assigned(Instance) then
Exit;
SetString(Result, PWideChar(NativeUInt(Instance) + Instance^.NameOffset), Instance^.NameLength div SizeOf(WideChar));
end;
procedure Main;
var
DiskInstance: Integer;
Data1, Data2: PPerfDataBlock;
begin
DiskInstance := 0; // first physical disk by default
if ParamCount > 0 then
DiskInstance := StrToInt(ParamStr(1));
Data1 := GetPerformanceData(IntToStr(ObjPhysicalDisk));
Writeln(Format('Disk instance %s', [GetDiskInstanceName(DiskInstance, Data1)]));
repeat
Sleep(1000);
Data2 := GetPerformanceData(IntToStr(ObjPhysicalDisk));
Writeln(Format('%.6f', [GetPhysicalDiskAvgSecPerRead(DiskInstance, Data1, Data2)]));
Data1 := Data2;
until False;
end;
begin
try
Main;
except
on E: Exception do
begin
ExitCode := 1;
Writeln(Format('[%s] %s', [E.ClassName, E.Message]));
end;
end;
end.
Fantastic. Благодаря! –