음......이번에는 프로세스 목록을 얻어오는 방법에 대해서 아주~간단히 알아보도록 하겠습니다.
프로세스 목록을 얻어오는 방법 중 간단히 2가지를 소개하자면,
첫째로, CreateToolhelp32Snapshot/Process32First/Process32Next 를 이용하는 간단한 방법입니다.
둘째로, NtQuerySystemInformation을 이용하는 방법이 있으나, 이 방법을 추가하면 코드가 약간 길어지므로 나중에 설명하겠습니다. [NT/2K/XP/2K3/Vista/...에서만 호환]
여기에서 소개하려는 주요 API는 다음과 같습니다. [Win9x에서도 호환됩니다.]
CreateToolhelp32Snapshot
Process32First
Process32Next
자, CreateToolhelp32Snapshot() 에 관해 알아봅시다.
이 API는 스냅샷 핸들을 얻어오는 역할을 합니다.
성공시 "올바른" 핸들을 반환합니다.
(잘못된 핸들로 취급되는 예:핸들 값이 NULL인 경우, 혹은 INVALID_HANDLE_VALUE(0xFFFFFFFF))
그리고 이렇게 얻어진 핸들의 사용이 끝나면, 다시 CloseHandle() API를 이용하여 핸들을 닫아주는게 좋습니다.
WINBASEAPI
HANDLE
WINAPI
CreateToolhelp32Snapshot(
IN DWORD th32Flags,
IN DWORD th32ProcessID);
th32Flags : TH32CS_SNAPPROCESS, TH32CS_SNAPMODULE, ...등의 상수가 있는데,
프로세스 목록을 얻으려면 TH32CS_SNAPPROCESS를, 모듈 목록을 얻으려면 TH32CS_SNAPMODULE, ....등을 넣으면 되는것 같습니다. 이 외에도 TH32CS_SNAPTHREAD, TH32CS_SNAPHEAPLIST가 있습니다.
이 상수를 이용해 얻어진 핸들은 일반적으로, Xxx32First/Xxx32Next 루틴으로 목록을 얻어올 수 있습니다.
예를 들어서, TH32CS_SNAPPROCESS를 인자로 사용하였다면, Process32First()/Process32Next() 루틴으로 목록을 얻어올 수 있는 것입니다.
th32ProcessID : 이 인자는 "여기에서는" 0을 줘도 무방합니다. 제 생각에는 Toolhelp32ReadProcessMemory() API와 관련이 있는 인자이기도 하지 않을까 싶군요. 여기에 유효한 Process ID를 인자로 주면 해당 Process ID에 해당하는 Process의 정보를 얻어 올 수 있지 않을까도 싶고요.
이제는 Process32First/Process32Next 에 관해 알아보겠습니다.
Process32First는 오직 첫번째 프로세스의 정보만을 가져옵니다.
그리고 Process32Next는 다음 프로세스가 없을 때까지 찾아서 다음 프로세스를 찾으면 정보를 가져오고, TRUE를 반환합니다.
인자는 똑같습니다.
둘 다, 성공시 TRUE를, 실패시 혹은 더이상 프로세스가 없을 시에는 FALSE를 반환합니다.
WINBASEAPI
BOOL
WINAPI
Process32First(
IN HANDLE hSnapshot,
OUT PPROCESSENTRY32 lpProcessEntry32Info);
WINBASEAPI
BOOL
WINAPI
Process32Next(
IN HANDLE hSnapshot,
OUT PPROCESSENTRY32 lpProcessEntry32Info);
hSnapshot : CreateToolhelp32Snapshot() 로 얻어온 "올바른" 스냅샷 핸들.
lpProcessEntry32Info : PROCESSENTRY32 의 포인터형. 만일 성공시 이 인자로 프로세스 정보가 넘어옵니다.
Process32First() 호출시, PROCESSENTRY32 구조체에는 반드시 PROCESSENTRY32::dwSize에 sizeof(PROCESSENTRY32) 를 넣어줘야 합니다.
으음 그리고 이것은 보너스.
이 API는 핸들을 닫는 역할을 하며, 성공시 TRUE, 실패시 FALSE를 반환합니다.
WINBASEAPI
BOOL
WINAPI
CloseHandle(
IN HANDLE hHandle);
hHandle : OpenProcess()/OpenFile()/CreateFile()/CreateToolhelp32Snapshot()/CreateFileMapping()/OpenFileMapping().... 등을 이용해서 얻어진 핸들. (FindWindow()로 얻어진 윈도우 핸들이나 GDI Object 등등은 포함되지 않습니다!)
이상 프로세스 목록을 얻는 데 필요한 API에 대해 대강 알아보았으므로, 한번 짜보겠습니다.
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
void PrintProcessList()
{
HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hSnapshot)
{
PROCESSENTRY32 ProcessEntry32;
BOOL bProcessFound;
ProcessEntry32.dwSize=sizeof(PROCESSENTRY32);
bProcessFound=Process32First(hSnapshot, &ProcessEntry32);
while(bProcessFound)
{
printf("%s [%d]\n", ProcessEntry32.szExeFile, ProcessEntry32.th32ProcessID);
bProcessFound=Process32Next(hSnapshot, &ProcessEntry32);
}
CloseHandle(hSnapshot);
}
}
void main()
{
PrintProcessList();
}
어떤가요? 코드가 생각보다 짧지 않나요?
어쨌거나 이상으로, 프로세스 목록을 얻어오는 간단한 방법에 대해서 알아보았습니다.
[출처] [API] 프로세스 목록 얻어오기.