Если очень долго думать, то на NT есть такая штука - Performance objects. Посмотри хотя бы в файла win32.hlp про то, как с ними работать. Я переписал пример, который там приводится на Delphi, получилось вот такое:
Const TotalBytes=8*1024;
ByteIncrement=8*1024;
Type PPerfDataBlock=^TPerfDataBlock;
TPerfDataBlock=packed record
Signature:array[1..4]of widechar;
LittleEndian:cardinal;
Version:cardinal;
Revision:cardinal;
TotalByteLength:cardinal;
HeaderLength:cardinal;
NumObjectTypes:cardinal;
DefaultObject:cardinal;
SystemTime:TSystemTime;
PerfTime:LARGE_INTEGER;
PerfFreq:LARGE_INTEGER;
PerfTime100nSec:LARGE_INTEGER;
SystemNameLength:cardinal;
SystemNameOffset:cardinal;
end;
PPerfObjectType=^TPerfObjectType;
TPerfObjectType=packed record
TotalByteLength:cardinal;
DefinitionLength:cardinal;
HeaderLength:cardinal;
ObjectNameTitleIndex:cardinal;
ObjectNameTitle:PWideChar;
ObjectHelpTitleIndex:cardinal;
ObjectHelpTitle:PWideChar;
DetailLevel:cardinal;
NumCounters:cardinal;
DefaultCounter:cardinal;
NumInstances:integer;
CodePage:cardinal;
PerfTime:LARGE_INTEGER;
PerfFreq:LARGE_INTEGER;
end;
PPerfCounterDefinition=^TPerfCounterDefinition;
TPerfCounterDefinition=packed record
ByteLength:cardinal;
CounterNameTitleIndex:cardinal;
CounterNameTitle:PWideChar;
CounterHelpTitleIndex:cardinal;
CounterHelpTitle:PWideChar;
DefaultScale:cardinal;
DetailLevel:cardinal;
CounterType:cardinal;
CounterSize:cardinal;
CounterOffset:cardinal;
end;
PPerfInstanceDefinition=^TPerfInstanceDefinition;
TPerfInstanceDefinition=packed record
ByteLength:cardinal;
ParentObjectTitleIndex:cardinal;
ParentObjectInstance:cardinal;
UniqueID:cardinal;
NameOffset:cardinal;
NameLength:cardinal;
end;
PPerfCounterBlock=^TPerfCounterBlock;
TPerfCounterBlock=packed record
ByteLength:cardinal;
end;
PBytes=^Bytes;
Bytes=array[1..1024*1024]of byte;
var hKeyPerfLib:HKEY;
Buf,BufSize,I,J:cardinal;
K:integer;
Data,Data2:PChar;
PerfData:PPerfDataBlock;
PerfObj:PPerfObjectType;
PerfInst:PPerfInstanceDefinition;
PerfCntr,CurCntr:PPerfCounterDefinition;
PtrToCntr:PPerfCounterBlock;
lpNameStrings:array of string;
LastObject,LastInstance:TTreeNode;
begin
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows NT\CurrentVersion\Perflib',
0,KEY_READ,hKeyPerflib)<>ERROR_SUCCESS then raise Exception.Create('Не смог открыть ключ Perflib');
BufSize:=sizeof(Buf);
RegQueryValueEx(hKeyPerflib,'Last counter',nil,nil,@Buf,@BufSize);
RegCloseKey(hKeyPerflib);
SetLength(lpNameStrings,Buf+1);
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows NT\CurrentVersion\Perflib\019',
0,KEY_READ,hKeyPerfLib)<>ERROR_SUCCESS then raise Exception.Create('Не смог открыть ключ Perflib\019');
RegQueryInfoKey(hKeyPerflib,nil,nil,nil,nil,nil,nil,nil,nil,@BufSize,nil,nil);
Inc(BufSize);GetMem(Data,BufSize);
RegQueryValueEx(hKeyPerflib,'Counter',nil,nil,PByte(Data),@BufSize);
GetMem(Data2,1024);I:=0;
repeat
J:=0;while(Data[I]<>#0)do begin Data2[J]:=Data[I];Inc(I);Inc(J);end;
Data2[J]:=#0;val(StrPas(Data2),Buf,K);if K<>0 then break;
Inc(I);if Data[I]=#0 then break;
J:=0;while(Data[I]<>#0)do begin Data2[J]:=Data[I];Inc(I);Inc(J);end;
Data2[J]:=#0;lpNameStrings[Buf]:=StrPas(Data2);
Inc(I);if Data[I]=#0 then break;
until false;
FreeMem(Data);FreeMem(Data2);
RegCloseKey(hKeyPerflib);
BufSize:=TotalBytes;GetMem(PerfData,BufSize);
while RegQueryValueEx(HKEY_PERFORMANCE_DATA,'Global',nil,nil,PByte(PerfData),@BufSize)=ERROR_MORE_DATA do begin
FreeMem(PerfData,BufSize);
Inc(BufSize,ByteIncrement);
GetMem(PerfData,BufSize);
end;
PerfObj:=PPerfObjectType(cardinal(PerfData)+PerfData.HeaderLength);
LastObject:=nil;Tree.Items.Clear;Tree.Items.BeginUpdate;
I:=0;While(I<PerfData.NumObjectTypes)do begin
LastObject:=Tree.Items.Add(LastObject,Format('Объект %u: %s',[PerfObj.ObjectNameTitleIndex,lpNameStrings[PerfObj.ObjectNameTitleIndex]]));
PerfCntr:=PPerfCounterDefinition(cardinal(PerfObj)+PerfObj.HeaderLength);
if(PerfObj.NumInstances>0)then begin
PerfInst:=PPerfInstanceDefinition(cardinal(PerfObj)+PerfObj.DefinitionLength);
K:=0;while(K<PerfObj.NumInstances)do begin
LastInstance:=Tree.Items.AddChild(LastObject,Format('Экземпляр %u: %s: ',[K,StrPas(pchar(cardinal(PerfInst)+PerfInst.NameOffset))]));
CurCntr:=PerfCntr;
J:=0;while(J<PerfObj.NumCounters)do begin
Tree.Items.AddChild(LastInstance,Format('Счетчик %u: %s',[CurCntr.CounterNameTitleIndex,lpNameStrings[CurCntr.CounterNameTitleIndex]]));
CurCntr:=PPerfCounterDefinition(cardinal(CurCntr)+PerfCntr.ByteLength);
Inc(J);
end;
PtrToCntr:=PPerfCounterBlock(cardinal(PerfInst)+PerfInst.ByteLength);
PerfInst:=PPerfInstanceDefinition(cardinal(PtrToCntr)+PtrToCntr.ByteLength);
Inc(K);
end;
end else if PerfObj.NumCounters>0 then begin
LastInstance:=Tree.Items.AddChild(LastObject,'Экземпляр 0');
J:=0;while(J<PerfObj.NumCounters)do begin
Tree.Items.AddChild(LastInstance,Format('Счетчик %u: %s',[PerfCntr.CounterNameTitleIndex,lpNameStrings[PerfCntr.CounterNameTitleIndex]]));
PerfCntr:=PPerfCounterDefinition(cardinal(PerfCntr)+PerfCntr.ByteLength);
Inc(J);
end;
end;
PerfObj:=PPerfObjectType(cardinal(PerfObj)+PerfObj.TotalByteLength);
inc(I);
end;
Tree.Items.EndUpdate;
RegCloseKey(HKEY_PERFORMANCE_DATA);
SetLength(lpNameStrings,0);
FreeMem(PerfData,BufSize);
end;
Этот код только получает список производительности и оформляет в виде дерева. Надо еще получать и расшифровывать сами счетчики, просто пока я на эту проблему забил, может, как нибуть позднее и сделаю. |