Вверх ↑
Разработчик
Ответов: 26158
Рейтинг: 2127
#1: 2011-05-17 00:35:34 ЛС | профиль | цитата
goluzov, вот почему я говорю, что очень сложно, когда у меня нет этих систем. Исправление компонента превращается в тупое слепое тыкание. Я нашел альтернативный вариант, пока говорить не буду, на чем и как он построен, но предполагает определение всего на любой системе. И опять все это виртуально, не имея всей базы для проверки
------------ Дoбавленo в 16.15:
goluzov, проверь вот этот код на всех системах



Add(MainForm,2953706,77,147)
{
link(onCreate,3394494:doEvent1,[])
}
Add(InlineCode,2850697,189,161)
{
WorkPoints=#13:doEnumProcess|
EventPoints=#13:onEnumProcess|
VarPoints=#14:CountProcesses|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|29:uses Windows,kol,Share,Debug;|0:|5:type |36: PPerfDataBlock = ^TPerfDataBlock; |26: TPerfDataBlock = record |37: Signature: array[0..3] of WCHAR; |25: LittleEndian: DWORD; |20: Version: DWORD; |21: Revision: DWORD; |28: TotalByteLength: DWORD; |25: HeaderLength: DWORD; |27: NumObjectTypes: DWORD; |28: DefaultObject: Longint; |29: SystemTime: TSystemTime; |29: PerfTime: TLargeInteger; |29: PerfFreq: TLargeInteger; |36: PerfTime100nSec: TLargeInteger; |29: SystemNameLength: DWORD; |29: SystemNameOffset: DWORD; |7: end; |0:|38: PPerfObjectType = ^TPerfObjectType; |27: TPerfObjectType = record |28: TotalByteLength: DWORD; |29: DefinitionLength: DWORD; |25: HeaderLength: DWORD; |33: ObjectNameTitleIndex: DWORD; |29: ObjectNameTitle: LPWSTR; |33: ObjectHelpTitleIndex: DWORD; |29: ObjectHelpTitle: LPWSTR; |24: DetailLevel: DWORD; |24: NumCounters: DWORD; |29: DefaultCounter: Longint; |27: NumInstances: Longint; |21: CodePage: DWORD; |29: PerfTime: TLargeInteger; |29: PerfFreq: TLargeInteger; |7: end; |0:|52: PPerfCounterDefinition = ^TPerfCounterDefinition; |34: TPerfCounterDefinition = record |23: ByteLength: DWORD; |34: CounterNameTitleIndex: DWORD; |30: CounterNameTitle: LPWSTR; |34: CounterHelpTitleIndex: DWORD; |30: CounterHelpTitle: LPWSTR; |27: DefaultScale: Longint; |24: DetailLevel: DWORD; |24: CounterType: DWORD; |24: CounterSize: DWORD; |26: CounterOffset: DWORD; |7: end; |0:|54: PPerfInstanceDefinition = ^TPerfInstanceDefinition; |35: TPerfInstanceDefinition = record |23: ByteLength: DWORD; |35: ParentObjectTitleIndex: DWORD; |33: ParentObjectInstance: DWORD; |23: UniqueID: Longint; |23: NameOffset: DWORD; |23: NameLength: DWORD; |7: end; |0:|42: PPerfCounterBlock = ^TPerfCounterBlock; |29: TPerfCounterBlock = record |23: ByteLength: DWORD; |6: end;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|30: FCountProcesses: integer;|9: public|30: onEnumProcess: THI_Event;|58: procedure doEnumProcess(var _Data:TData; Index:word);|64: procedure CountProcesses(var _Data:TData; Index:word); |5: end;|0:|14:implementation|0:|36:procedure THiAsmClass.doEnumProcess;|5:const|56: INCREMENTAL_SIZE = 32768; // Шаг увеличения буфера|58: INITIAL_BUFFER_SIZE = 65536; // Начальный размер буфера|57: PROCESS_OBJECT_INDEX = 230; // Индекс объекта Process|67: PID_OBJECT_INDEX = 784; // Индекс счетчика ID Process (PID)|3:var|41: buflen: DWORD; // текущий размер буфера|46: PerfData: PPerfDataBlock; // PERF_DATA_BLOCK|47: PerfObj: PPerfObjectType; // PERF_OBJECT_TYPE|72: PerfCntr, CurCntr: PPerfCounterDefinition; // PERF_COUNTER_DEFINITION|65: PerfInst: PPerfInstanceDefinition; // PERF_INSTANCE_DEFINITION|68: PerfCntrBlk, PtrToCntr: PPerfCounterBlock; // PERF_COUNTER_BLOCK|38: i,k,j: Integer; // счетчики в циклах|42: process_name: String; // выходная строка|55: pData: PLargeInteger; // Указатель на данные счетчика|5:begin|23: FCountProcesses := 0;|32: buflen := INITIAL_BUFFER_SIZE;|55: GetMem(PerfData, buflen); // Выделяем начальный буфер|5: try|39: // Пытаемся заполнить буфер данными|86: while RegQueryValueEx(HKEY_PERFORMANCE_DATA, PChar(Int2Str(PROCESS_OBJECT_INDEX)),|82: nil,nil,Pointer(PerfData), @buflen) = ERROR_MORE_DATA do|71: begin // Если буфер маленький, то увеличиваем его и снова пытаемся|35: inc(buflen,INCREMENTAL_SIZE);|35: ReallocMem(PerfData, buflen);|8: end;|75: RegCloseKey(HKEY_PERFORMANCE_DATA); // Обязательно закрываем этот ключ.|80: // Получаем указатель на первую структуру PERF_OBJECT_TYPE (первый инфоблок)|72: PerfObj := PPerfObjectType(DWORD(PerfData) + PerfData.HeaderLength);|46: // Перебираем все полученные типы объектов|48: for i := 0 to PerfData.NumObjectTypes - 1 do|9: begin|41: // Ищем объект Process (индекс 230)|65: if PerfObj.ObjectNameTitleIndex = PROCESS_OBJECT_INDEX then|11: begin|77: // Запоминаем расположение описаний счетчиков PERF_COUNTER_DEFINITION|82: PerfCntr := PPerfCounterDefinition(DWORD(PerfObj) + PerfObj.HeaderLength);|61: // Получаем экземпляры объекта Process, если они есть|40: if PerfObj.NumInstances > 0 then|13: begin|76: // Получаем указатель на первую структуру PERF_INSTANCE_DEFINITION|89: PerfInst := PPerfInstanceDefinition(DWORD(PerfObj) + PerfObj.DefinitionLength);|46: // Перебираем все экземпляры объекта|51: for k := 0 to PerfObj.NumInstances - 1 do|15: begin|62: // Получаем имя текущего экземпляра (имя процесса)|95: process_name := WideCharToString(PWideChar(DWORD(PerfInst) + PerfInst.NameOffset));|68: // Если имя равно '_Total', то пропускаем этот экземпляр|59: // т.к. это суммарные данные для всех процессов|53: if process_name = '_Total' then Continue;|75: // Получаем указатель на первый счетчик PERF_COUNTER_DEFINITION|32: CurCntr := PerfCntr;|73: // Получаем указатель на данные счетчиков текущего экземпляра|33: // PERF_COUNTER_BLOCK|82: PtrToCntr := PPerfCounterBlock(DWORD(PerfInst) + PerfInst.ByteLength);|57: //Перебираем все счетчики для каждого объекта|52: for j := 0 to PerfObj.NumCounters - 1 do|17: begin|54: // Получаем указатель на данные счетчика|73: pData := Pointer(DWORD(PtrToCntr) + CurCntr.CounterOffset);|91: // Если счетчик - это ID Process, то читаем его и добавляем в выходную строку|70: if CurCntr.CounterNameTitleIndex = PID_OBJECT_INDEX then|19: begin|78: process_name := process_name + ';' + Int2Str(Integer(pData^));|37: inc(FCountProcesses);|18: end;|56: // Получаем указатель на следующий счетчик|86: CurCntr := PPerfCounterDefinition(DWORD(CurCntr) + CurCntr.ByteLength); |18: end; |54: // Добавляем выходную строку в TStringList|53: _hi_onEvent(onEnumProcess, process_name);|64: // Получаем указатель на следующий экземпляр объекта|64: // Он находится сразу за данными текущего экземпляра|84: PerfCntrBlk := PPerfCounterBlock(DWORD(PerfInst) + PerfInst.ByteLength);|93: PerfInst := PPerfInstanceDefinition(DWORD(PerfCntrBlk) + PerfCntrBlk.ByteLength);|14: end;|12: end;|10: end;|52: // Получаем указатель на следующий тип объекта|75: PerfObj := PPerfObjectType(DWORD(PerfObj) + PerfObj.TotalByteLength);|8: end;|9: finally|57: // В любом случае освобождаем память, занятую буфером|22: FreeMem(PerfData);|6: end;|6:end; |0:|37:procedure THiAsmClass.CountProcesses;|5:begin|36: dtInteger(_Data, FCountProcesses);|4:end;|0:|4:end.|
link(onEnumProcess,1548553:doAdd,[])
}
Add(StringTable,1548553,245,161)
{
Width=384
Height=262
Align=5
Columns=#16:Name Process=250|7:PID=100|
}
Add(StatusBar,5638070,245,217)
{
}
Add(Hub,3394494,133,161)
{
link(onEvent1,2850697:doEnumProcess,[])
link(onEvent2,4324632:doStrCat,[(165,174)(165,223)])
}
Add(StrCat,4324632,182,217)
{
Str1="Processes : "
link(onStrCat,5638070:doText,[])
link(Str2,2850697:CountProcesses,[])
}

------------ Дoбавленo в 00.35:
Во млин. Куда-то бетатестер исчез
карма: 22

0