Victor_Dobrov
Advanced Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору unit Sample3; interface uses Windows, Classes, SysUtils; const // Уровни детализации PERF_DETAIL_NOVICE = 100; // Новичок PERF_DETAIL_ADVANCED = 200; // Продвинутый PERF_DETAIL_EXPERT = 300; // Эксперт PERF_DETAIL_WIZARD = 400; // Максимальный PDH_MORE_DATA = -2147481646; //Все данные не помещаются в предоставленный буфер function FillProcessesList(var slProcesses: TStringList): Boolean; implementation function PdhEnumObjectItems(szDataSource: PChar; szMachineName: PChar; szObjectName: PChar; mszCounterList: PChar; pcchCounterListLength: PDWORD; mszInstanceList: PChar; pcchInstanceListLength: PDWORD; dwDetailLevel: DWORD; dwFlags: DWORD ): LongInt; stdcall; external 'PDH.DLL' name 'PdhEnumObjectItemsA'; function FillProcessesList(var slProcesses: TStringList): Boolean; var pdhStatus: LongInt; // Возвращаемое значение PDH-функций sObjectName: array [0..7] of Char; // Буфер для имени объекта "Process" pCounterList: PAnsiChar; // Буфер для списка счетчиков CounterListLength: DWORD; // Длина буфера для списка счетчиков pInstanceList: PAnsiChar; // Буфер для списка экземпляров (процессов), после заполнения здесь будет цепочка нультерминальных строк и в конце общий #0. InstanceListLength: DWORD;// Длина буфера для списка экземпляров pThisInstance: PAnsiChar; // Указатель на имя текущего экземпляра begin Result := False; sObjectName := 'Process'; // Собираемся получить список процессов CounterListLength := 0; // Обнуляем длины буферов InstanceListLength := 0; // В первый вызов функции вместо буферов ставим nil и получаем длины буферов pdhStatus := PdhEnumObjectItems(nil, // информация реального времени nil, // локальная машина @sObjectName, // Имя объекта nil, @CounterListLength, // передаем 0 nil, @InstanceListLength,// передаем 0 PERF_DETAIL_WIZARD, //Максимальная детализация 0); // PdhEnumObjectItems должна вернуть PDH_MORE_DATA, если нет - ошибка if pdhStatus = PDH_MORE_DATA then begin // Резервируем память под буферы GetMem(pCounterList, CounterListLength); GetMem(pInstanceList, InstanceListLength); try // Вторым вызовом функции получаем информацию pdhStatus := PdhEnumObjectItems(nil, // информация реального времени nil, // локальная машина @sObjectName, // Имя объекта pCounterList, // Буфер счетчиков @CounterListLength, pInstanceList, // Буфер имен @InstanceListLength, PERF_DETAIL_WIZARD, 0); // Проверяем успешность выполнения функции PdhEnumObjectItems if pdhStatus = ERROR_SUCCESS then begin // Ставим указатель на начало буфера экземпляров pThisInstance := pInstanceList; // Крутим цикл пока не кончатся имена (в конце буфера стоит #0) while pThisInstance^ <> #0 do begin // Пропускаем экземпляр с общими данными if pThisInstance <> '_Total' then // Добавляем имя процесса к списку slProcesses.Add(pThisInstance); // Перемещаем указатель на следующее имя inc(pThisInstance, Length(pThisInstance)+1); end; // Фунция сработала успешно, если досюда дошло Result := True; end; finally // В любом случае освобождаем память буферов FreeMem(pCounterList); FreeMem(pInstanceList); end; end; end; end. |