Programming/Win32 API2008. 12. 3. 10:04

음......이번에는 프로세스 목록을 얻어오는 방법에 대해서 아주~간단히 알아보도록 하겠습니다.

프로세스 목록을 얻어오는 방법 중 간단히 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();
}

 

어떤가요? 코드가 생각보다 짧지 않나요?

어쨌거나 이상으로, 프로세스 목록을 얻어오는 간단한 방법에 대해서 알아보았습니다.

Posted by skensita