unit Sample3;
interface
uses Windows, Classes, SysUtils;
type
NTSTATUS = Cardinal;
const
SystemProcessesAndThreadsInformation = 5;
STATUS_SUCCESS = NTSTATUS($00000000);
type
.
. // Вырезано для краткости [COLOR="Red"]ЧТО ЗДЕСЬ АВТОР ВЫРЕЗАЛ???[/COLOR]
.
PUnicodeString = ^TUnicodeString;
TUnicodeString = packed record
Length: Word; // Длина строки без терминального нуля
MaximumLength: Word; // Полная длина буфера
Buffer: PWideChar; // Указатель на буфер для UNICODE-строки
end;
.
. // Вырезано [COLOR="Red"]ЧТО ЗДЕСЬ АВТОР ВЫРЕЗАЛ???[/COLOR]
.
PSYSTEM_PROCESSES = ^SYSTEM_PROCESSES;
SYSTEM_PROCESSES = packed record
NextEntryDelta, // Смещение следующей структуры от начала этой
ThreadCount: dword; // Количество потоков процесса
Reserved1 : array [0..5] of dword;
CreateTime, // Временные характеристики процесса
UserTime,
KernelTime: LARGE_INTEGER;
ProcessName: TUnicodeString; // Имя процесса
BasePriority: dword; // Базовый приоритет
ProcessId, // Идентификатор процесса – PID
InheritedFromProcessId, // PID родителя
HandleCount: dword; // Открытые дестрипторы
Reserved2: array [0..1] of dword;
// Счетчики с инфой об использовании памяти и системы ввода-вывода.
VmCounters: VM_COUNTERS; [COLOR="Red"]Не распознается!!! ПОЧЕМУ???[/COLOR]
IoCounters: IO_COUNTERS; // Windows 2000 only [COLOR="Red"]Не распознается!!! ПОЧЕМУ???[/COLOR]
// Массив структур с инфой о потоках процесса
Threads: array [0..0] of SYSTEM_THREADS; [COLOR="Red"]Не распознается!!! ПОЧЕМУ???[/COLOR]
end;
function FillProcessesList(var slProcesses: TStringList): Boolean;
implementation
function ZwQuerySystemInformation(dwSystemInformationClass: DWORD;
pSystemInformation: Pointer;
dwSystemInformationLength: DWORD;
var iReturnLength:DWORD): NTSTATUS;
stdcall;external 'ntdll.dll';
function FillProcessesList(var slProcesses: TStringList): Boolean;
var
ret: NTSTATUS;
pBuffer, pCur: PSYSTEM_PROCESSES;
ReturnLength: DWORD;
i: Integer;
ProcessName: String;
begin
Result := False;
ReturnLength := 0;
// Запрашиваем размер требуемого буфера
ret := ZwQuerySystemInformation(SystemProcessesAndThreadsInformation,
nil,
0,
ReturnLength);
// Резервируем буфер
pBuffer := AllocMem(ReturnLength);
// Получаем информацию о процессах в буфер
ret := ZwQuerySystemInformation(SystemProcessesAndThreadsInformation,
pBuffer,
ReturnLength,
ReturnLength);
if ret = STATUS_SUCCESS then // Проверяем успешность выполнения запроса
begin
pCur := pBuffer; // Инициируем указатель на текущую структуру
i := 0; // Инициируем счетчик процессов. Его можно и не использовать.
// Проходим в цикле по всей цепочке структур
repeat
inc(i); // Увеличиваем счетчик процессов.
// Смотрим длину имени процесса и если оно не равно 0,
// то читаем строку из буфера, иначе – имя = <неизвестно>
if pCur.ProcessName.Length = 0 then ProcessName := '<неизвестно>'
else ProcessName := WideCharToString(pCur.ProcessName.Buffer);
// Добавляем инфу о процессе в TStringList
slProcesses.Add(IntToStr(i) + ' -' +
' Имя: ' + ProcessName +
' PID: ' + IntToStr(pCur.ProcessId) +
' Приоритет: ' + IntToStr(pCur.BasePriority) +
' Потоков: ' + IntToStr(pCur.ThreadCount) +
' Дескрипторов: ' + IntToStr(pCur.HandleCount));
// Вычисляем указатель на следующую структуру SYSTEM_PROCESSES
// Для этого к адресу этой структуру прибавляем смещение следующей
// из поля NextEntryDelta
pCur := Ptr(DWORD(pCur) + pCur.NextEntryDelta);
// Крутим цикл, пока есть следующая структура
until pCur.NextEntryDelta = 0;
Result := True;
end;
FreeMem(pBuffer);
end;
end.
Просмотр всех процессов в памяти
Кто знает как просмотреть (средствами Делфи), какие процессы находятся в памяти, а также их PID, процессорное время, выделенную память, приоритет и прочую служебную атрибутику? Хотя бы подскажите в каком направлении копать...
Спасибо.
здесь есть пример получения списка процессов через эту функцию
ahilles, прогулялся я по твоей ссылке, решил попробовать пример на деле, и у меня возникли вопросы
Код:
PClientID = ^TClientID;
TClientID = packed record
UniqueProcess:DWORD;
UniqueThread:DWORD;
end;
PVM_COUNTERS = ^VM_COUNTERS;
VM_COUNTERS = packed record
PeakVirtualSize,
VirtualSize,
PageFaultCount,
PeakWorkingSetSize,
WorkingSetSize,
QuotaPeakPagedPoolUsage,
QuotaPagedPoolUsage,
QuotaPeakNonPagedPoolUsage,
QuotaNonPagedPoolUsage,
PagefileUsage,
PeakPagefileUsage: DWORD;
end;
PSYSTEM_THREADS = ^SYSTEM_THREADS;
SYSTEM_THREADS = packed record
KernelTime,
UserTime,
CreateTime: LARGE_INTEGER;
WaitTime: DWORD;
StartAddress: Pointer;
ClientId: TClientID;
Priority,
BasePriority,
ContextSwitchCount: DWORD;
State: DWORD;
WaitReason: DWORD;
end;
PIO_COUNTERS = ^IO_COUNTERS;
IO_COUNTERS = packed record
ReadOperationCount,
WriteOperationCount,
OtherOperationCount,
ReadTransferCount,
WriteTransferCount,
OtherTransferCount: LARGE_INTEGER;
end;
TClientID = packed record
UniqueProcess:DWORD;
UniqueThread:DWORD;
end;
PVM_COUNTERS = ^VM_COUNTERS;
VM_COUNTERS = packed record
PeakVirtualSize,
VirtualSize,
PageFaultCount,
PeakWorkingSetSize,
WorkingSetSize,
QuotaPeakPagedPoolUsage,
QuotaPagedPoolUsage,
QuotaPeakNonPagedPoolUsage,
QuotaNonPagedPoolUsage,
PagefileUsage,
PeakPagefileUsage: DWORD;
end;
PSYSTEM_THREADS = ^SYSTEM_THREADS;
SYSTEM_THREADS = packed record
KernelTime,
UserTime,
CreateTime: LARGE_INTEGER;
WaitTime: DWORD;
StartAddress: Pointer;
ClientId: TClientID;
Priority,
BasePriority,
ContextSwitchCount: DWORD;
State: DWORD;
WaitReason: DWORD;
end;
PIO_COUNTERS = ^IO_COUNTERS;
IO_COUNTERS = packed record
ReadOperationCount,
WriteOperationCount,
OtherOperationCount,
ReadTransferCount,
WriteTransferCount,
OtherTransferCount: LARGE_INTEGER;
end;
Когда добавил выше указанное, программа запустилась, но в процессе работы функции поиска процессов, описанной в примере, возникает ошибка доступа к адресу (см. вложения). В чем дело? Ты сам пробовал? Работает?
в прицепе есть мой пример получения списка процессов: там выводится только имя процесса и его нагрузка на процессор.
остальные данные смотри в структуре PSYSTEM_PROCESSES, с помощью которой описан каждый процесс.