Читаем О чём не пишут в книгах по Delphi полностью

Для получения списка процессов необходимо сделать "снимок" состояния системы с помощью функции CreateToolhelp32Snapshot. Эта функция создает специальный объект, который может хранить информацию о процессах, модулях, нитях и кучах, созданных в системе. Этот объект называется снимком потому, что информация, хранящаяся в нем, актуальна на момент вызова функции CreateToolhelp32Snapshot; дальнейшие изменения списка процессов, модулей и т.п. не приводят к изменению снимка. Доступ к снимку, как и к большинству объектов системы, осуществляется через его дескриптор. В данном случае функция CreateToolhelp32Snapshot вызывается с параметром TH32CS_SNAPPROCESS для получения списка процессов.

Навигация по списку процессов, сохраненных в снимке, осуществляется с помощью функций Process32First и Process32Next. Они позволяют получить ряд параметров процесса, главный среди которых — идентификатор процесса (Process Identifier, PID). Это уникальный идентификатор процесса, с помощью которого можно отличать один процесс от другого. 

Примечание

Не следует путать идентификатор процесса и дескриптор объекта процесса, который используется, например, в функции SetPriorityClass. Объект процесса — это специальный объект, связанный с процессом, но не тождественный ему. В частности, объект процесса может продолжать существовать уже после того, как сам процесс завершит работу (это позволяет, например, корректно синхронизироваться с уже завершенным процессом при помощи функции WaitForSingleObject). Через объект процесса можно управлять многими свойствами процесса. Поучить дескриптор объекта процесса по идентификатору процесса можно с помощью функции OpenProcess.

Код для получения списка процессов показан в листинге 1.42.

Листинг 1.42. Получение списка процессов с помощью Tool Help

procedure TProcessesInfoForm.FillProcessList;

var

 SnapProc: THandle;

 ProcEntry: TProcessEntry32;

 Item: TListItem;

begin

 ClearAll;

 // Создаем снимок, в котором сохраняем все процессы, а

 // затем в цикле получаем информацию о каждом из этих

 // процессов, перенося ее в ListProcesses

 SnapProc := CreateToolhelp32Snapshot(TH32CS_SNAPROCESSES, 0);

 if SnapProc <> INVALID_HANDLE_VALUE then

 try

  ProcEntry.dwSize := SizeOf(TProcessEntry32);

  if Process32First(SnapProc, ProcEntry) then repeat

   Item := ListProcesses.Items.Add;

   Item.Caption := ProcEntry.szExeFile;

   Item.SubItems.Add(IntToStr(ProcEntry.tb32ProcessID);

   Item.SubItems.Add(IntToStr(ProcEntry.th32ParentProcessID));

   Item.SubItems.Add(IntToStr(ProcEntry.cntThreads));

   // Сохраняем PID в поле Data соответствующего

   // элемента списка. Вообще, поле Data имеет тип

   // Pointer, а PID - это целое число, но т.к. оба этих

   // типа 32-битные, их можно приводить друг к другу

   Item.Data := Pointer(ProcEntry.th32ProcessID);

  until not Process32Next(SnapProc, ProcEntry);

 finally

  CloseHandle(SnapProc);

 end

 else

 begin

  ListProcesses.Visible := False;

  LabelProcessError.Caption :=

   'Невозможно получить список процессов:'#13#10'Ошибка №' +

   IntToStr(GetLastError);

 end;

end;

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже