← На главную

Получаем список запущенных процессов на Windows API

А тем временем я все продолжаю ностальгировать по сишечке и WinAPI. Сегодня совместными усилиями мы вспомним, как на WinAPI получить список запущенных процессов, а также динамических библиотек, используемых этими процессами.

Для этого нам понадобятся следующие процедуры и структуры.

CreateToolhelp32Snapshot(dwFlags, dwProcessId);

CreateToolhelp32Snapshot создает снапшот запущенных процессов, модулей, нитей и так далее. Аргумент dwFlags определяет, снапшот чего именно мы хотим получить. Некоторые возможные значения – TH32CS_SNAPPROCESS, TH32CS_SNAPMODULE, TH32CS_SNAPTHREAD. Параметр dwProcessId задает идентификатор процесса, для которого создается снапшот. Может быть ненужным и устанавливаться в ноль в зависимости от dwFlags. В случае успеха процедура возвращает хэндл снапшота, который должен быть потом закрыт с помощью уже знакомой нам процедуры CloseHandle. В случае ошибки возвращается значение INVALID_HANDLE_VALUE, а подробности поможет узнать GetLastError.

Process32First(hSnapshot, &peProcessEntry);

Process32First принимает хэндл, полученный от CreateToolhelp32Snapshot, вызванной с dwFlags = TH32CS_SNAPPROCESS, а также указатель на структуру PROCESSENTRY32. Перед вызовом процедуры поле dwSize этой структуры должно быть установлено в sizeof(PROCESSENTRY32). В случае успеха возвращается TRUE, а в peProcessEntry записывается информация о первом процессе. В случае ошибки возвращается FALSE, а подробности поможет узнать GetLastError.

Process32Next(hSnapshot, &peProcessEntry);

Процедура Process32Next работает полностью аналогично Process32First, но служит для получения второго и последующих процессов.

Еще мы воспользуемся процедурами Module32First и Module32Next, а также структурой MODULEENTRY32. Семантика у этих процедур полностью аналогична Process32First и Process32Next, только служат они для перечисления модулей в заданном процессе (CreateToolhelp32Snapshot с параметром dwFlags, равным TH32CS_SNAPMODULE).

Проще всего понять, как все это работает, посмотрев на пример кода:

#include <windows.h> #include <tlhelp32.h> VOID PrintModuleList(HANDLE CONST hStdOut, DWORD CONST dwProcessId) { MODULEENTRY32 meModuleEntry; TCHAR szBuff[1024]; DWORD dwTemp; HANDLE CONST hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId); if(INVALID_HANDLE_VALUE == hSnapshot) { return; } meModuleEntry.dwSize = sizeof(MODULEENTRY32); Module32First(hSnapshot, &meModuleEntry); do { wsprintf(szBuff, L" ba: %08X, bs: %08X, %s\r\n", meModuleEntry.modBaseAddr, meModuleEntry.modBaseSize, meModuleEntry.szModule); WriteConsole(hStdOut, szBuff, lstrlen(szBuff), &dwTemp, NULL); } while(Module32Next(hSnapshot, &meModuleEntry)); CloseHandle(hSnapshot); } VOID PrintProcessList(HANDLE CONST hStdOut) { PROCESSENTRY32 peProcessEntry; TCHAR szBuff[1024]; DWORD dwTemp; HANDLE CONST hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0); if(INVALID_HANDLE_VALUE == hSnapshot) { return; } peProcessEntry.dwSize = sizeof(PROCESSENTRY32); Process32First(hSnapshot, &peProcessEntry); do { wsprintf(szBuff, L"=== %08X %s ===\r\n", peProcessEntry.th32ProcessID, peProcessEntry.szExeFile); WriteConsole(hStdOut, szBuff, lstrlen(szBuff), &dwTemp, NULL); PrintModuleList(hStdOut, peProcessEntry.th32ProcessID); } while(Process32Next(hSnapshot, &peProcessEntry)); CloseHandle(hSnapshot); } INT main() { HANDLE CONST hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); PrintProcessList(hStdOut); ExitProcess(0); }

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

Как обычно, вы можете собрать эту программу не только под Visual Studio, но и при помощи MinGW, а затем запустить под Wine. В качестве домашнего задания можете изменить программу так, чтобы она также выводила информацию о нитях, используемых в каждом из запущенных процессов. Для этого вам понадобятся процедуры Thread32First, Thread32Next, а также структура THREADENTRY32.

Дополнение: Автозапуск программы на чистом Windows API