Главная > Программирование, системное > WinAPI: Получить список запущенных процессов на Delphi.

WinAPI: Получить список запущенных процессов на Delphi.

Я считаю что данная тема довольно актуальна и для своих программ иногда приходится придумывать механизмы которые к примеру не позволяли запускать одновременно несколько копий программ. Для реализации такого механизма достаточно описать в своем проекте функцию получения списка запущенных процессов и в зависимости от своих нужд работать с полученным списком.

Ниже приведен пример программы которая выводит список процессов. Все комментарии смотрите в исходнике.


unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls,PSAPI, TlHelp32;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}

function GetProcessList(): TStrings;
var
eP: TProcessEntry32;
hP, snap: THandle; //дескрипторы процесса и снимка
hM: hmodule; //дескриптор модуля
prcs: array[0..$FFF] of dword; //массив для хранения
// дескрипторов процессов
cP, cM: cardinal; //количество процессов
i: integer;
NameProc: array[0..max_path] of char; //имя модуля
lP: TStrings;
begin
lP:=TStringList.Create;
lP.Clear;
//проверяем версию винды
if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then
begin //если это Win9x
//инициализируем переменные
snap := CreateToolhelp32Snapshot(th32cs_snapprocess, 0);
if integer(snap) = -1 then
begin
exit;
end
else
begin
eP.dwSize := sizeof(eP);
//для Win9x получение списка процессов выполняется по
//аналогии с поиском файлов
//вызываем функцию для получения первого процесса
if Process32First(snap, eP) then
//а далее в цикле пока еще есть процессы получаем следующий
repeat
lP.Add(string(eP.szExeFile));//получаем имя процесса
until not Process32Next(snap, eP);
end;
end
else
begin //Если WinNT/2000/XP
//то в этом случае мы пользуемся Api-функцией перечисления
// запущенных процессов
//которая заполняет нам наши переменные
if not EnumProcesses(@prcs, sizeof(prcs), cP) then
begin
exit;
end;
//и далее для каждого дескриптора процесса получаем о нем
// информацию
for i := 0 to cP div 4 - 1 do
begin
hP := OpenProcess(PROCESS_QUERY_INFORMATION or
PROCESS_VM_READ,
false, prcs[i]);
if hP > 0 then
begin
EnumProcessModules(hP, @hM, 4, cM);
GetModuleFileNameEx(hP, hM, NameProc, sizeof(NameProc));
lP.Add(ExtractFileName(string(NameProc))); //если вы хотите
// получить только имена процессов
// lP.Add(string(NameProc)); //если вы хотите получить
// имена процессов вместе c путем
CloseHandle(hP);
end;
end;
end;
GetProcessList:=lP; //возвращаем полученный список
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
memo1.Lines:=GetProcessList;
end;
end.

Пожалуйста, оцените полезность и качество данной статьи. Одна звезда - плохо, 5 - хорошо.
1/5. Мы будем признательны, если вы напишете комментарий с причиной низкой оценки.2/5. Мы будем признательны, если вы напишете комментарий с причиной низкой оценки.3/5. Мы будем признательны, если вы напишете комментарий с причиной низкой оценки.4/5.5/5. (4 голосов, средний: 5,00 из 5)
Загрузка...
  1. Александр
    5 февраля 2009 в 17:53 | #1

    prcs: array[0..$FFF] of dword; //массив для хранения

    Вот это не самый правильный фрагмент. Если в системе более, чем 4096 процессов, то только первые 4096 попадут в список. Документация говорит, что если размер использованного буфера cP после функции EnumProcesses равен размеру вашего буфера, то надо снова вызвать EnumProcesses с уже большим буфером. И так до тех пор, пока ваш буфер не будет заполняться до конца. Вот такая вот виндовая технология. ;-)

    Понятно, что для домашнего компьютера 4096 весьма значительная и слабо достижимая цифра, но вот для промышленных систем - легко. У нас один банк, работающий на виндах, имеет только одних телнет-соединений более 4000 (уже по одному процессу на соеденение). Так что там количество процессов гораздо больше 4096.

    Почему знаю, потому что писал аналогичную функцию и наступил на эти грабли. ;-)

  2. C0ffe1n
    5 февраля 2009 в 18:20 | #2

    @Александр
    Согласен, но не думал что может быть их так много!Оо Спасибо, ценное замечание. =)

  3. adsasd
    17 мая 2014 в 00:29 | #3

    А как на листбокс поставить?

  4. Аноним
    18 января 2015 в 14:59 | #4

    @ adsasd
    ТЫ нуб. сменить название компонента и все

  1. Пока что нет уведомлений.