Рейтинг@Mail.ru

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


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

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

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 звезда2 звезды3 звезды4 звезды5 звёзд (7 голосов, средний: 5,00 из 5)
Loading ... Loading ...

  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. 4 Февраль 2010 в 16:16 | #3

    По поводу ограничения на повторный запуск копии своей программы это не лучший вариант. С помощью WinAPI ф-ции CreateMutex создается собственно сам мьютекс уникальный для вашей программы. При запуске второго экземпляра вашей проги попытка создать мьютекс с тем же именем будет неудачность. Значит ваша прога уже запущена. И не нужно никакой возни с процессами.

  4. C0ffe1n
    5 Февраль 2010 в 17:13 | #4

    Верно, но ведь это лишь пример, как можно использовать данный алгоритм, возможно не много не удачный… также другими примерами может стать контроль или монитор процессов и т.п. а это уже читателю решать где данный механизм можно применить. Но спасибо большое за столь ценный совет, это приятно :)

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