오늘은 작업관리자에서 강제로 프로세스를 종료하는 방법이 있는데 이런 방법을 프로그램을 하는 것에 대해 설명하고자 합니다.


보통 메인 프로그램이 서브프로그램을 강제로 종료시킬 때 sendmessage 을 통해서 종료를 시키게 되는데 해당 프로그램이 lock이 걸렸거나 이벤트를 받지를 못하는 상황이 생겼을 때 위 메세지는 의미가 없게 된다.


그렇기에 강제로 프로세스를 종료를 시켜야 하는데 이에 사용한 함수를 소개 하고자 합니다.


** 소스코드


// CString strProcessName : 프로세스 파일명.확장자

BOOL Util::ProcessKill(CString strProcessName)

{

HANDLE hProcessSnap = NULL;

BOOL bRet = FALSE; 

PROCESSENTRY32 pe32 = {0}; 


hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 

if (hProcessSnap == (HANDLE)-1) 

return false;

pe32.dwSize = sizeof(PROCESSENTRY32); 


//프로세스가 메모리상에 있으면 첫번째 프로세스를 얻는다

if (Process32First(hProcessSnap, &pe32)) 

BOOL bCurrent = FALSE; 

MODULEENTRY32 me32 = {0}; 


do { 

bCurrent = GetProcessModule(pe32.th32ProcessID,strProcessName);

if(bCurrent) { 

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID); 

if(hProcess) {

if(TerminateProcess(hProcess, 0)) {

unsigned long nCode; //프로세스 종료 상태 

GetExitCodeProcess(hProcess, &nCode);

}

CloseHandle(hProcess); 

}

}

}

//다음 프로세스의 정보를 구하여 있으면 루프를 돈다.

while (Process32Next(hProcessSnap, &pe32)); 


CloseHandle (hProcessSnap); 

return true;

}



// 위 함수애서 호출되는 것으로 해당 프로세스아이디, 이름이 존재하는지 찾는다.'

// DWORD dwPID : 프로세스아이디

// CString sProcessName : 프로세스파일명.확장자

BOOL Util::GetProcessModule(DWORD dwPID, CString sProcessName)

{

HANDLE hModuleSnap = NULL;

MODULEENTRY32 me32 = {0};


hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID); 

if(hModuleSnap == (HANDLE)-1) 

return (FALSE); 

me32.dwSize = sizeof(MODULEENTRY32); 


//해당 프로세스의 모듈리스트를 루프로 돌려서 프로세스이름과 동일하면 

//true를 리턴한다.

if(Module32First(hModuleSnap, &me32)) { 

do { 

if(me32.szModule == sProcessName)

CloseHandle (hModuleSnap); 

return true;


while(Module32Next(hModuleSnap, &me32)); 


CloseHandle (hModuleSnap); 

return false;

}


* 사용법


BOOL ret = m_util.ProcessKill("aaa.exe");


작업관리자에서 보이는 파일명.확장을 인자로 넘기면 됩니다. 대소문자 구분도 하니 보이는 그대로 인자를 넘겨야 합니다.











오늘은 해당 프로그램이 실행중인지 확인하는 함수를 소개하고자 합니다.

보통 FindWindow 을 사용하면 되지만.. 부팅 시 자동실행이나 PC의 부하가 많은 상태에서는 FindWindow 로는 해당 window을 찾지 못하는 경우가 있습니다.

그래서 직접 작업관리자에서 해당 파일이 실행중인지 확인해서 해당 핸들을 얻는 방법이 가장 정확한 방법이기에 소개합니다.


보통 FindWindow 로 먼저 처리하고, 프로그램을 운영을 하면서 FindWindow 가 통과하는 경우가 발생하면 CreateToolhelp32Snapshot 울 이용을 하개 됩니다..




* 소스코드


// CString parm_exe : exe 파일명

// DWORD parm_id : 프로세스 아이디 (모르는 경우 -1 사용)

int Util::FindDoubleProcess(CString parm_exe, DWORD parm_id)

{

int ret_val = 0;

BOOL bGet = FALSE;

CString read_name;

CString parm_exe_lower = parm_exe;

HANDLE hSnapshot;

PROCESSENTRY32 ppe; //구성된 자료구조를 저장하기 위한 엔트리.



hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//system 프로세서(pid=0)의 상태를 읽어 온다

ppe.dwSize = sizeof(PROCESSENTRY32);    //엔트리 구조체 사이즈를 정해준다.

bGet = Process32First(hSnapshot, &ppe); //엔트리 중 자료를 가져온다.

parm_exe_lower.MakeLower();

while (bGet){

read_name = ppe.szExeFile;

read_name.MakeLower();

if( read_name == parm_exe && parm_id != ppe.th32ProcessID ){

int dd = ppe.th32ProcessID;

ret_val = 1; break;

}

bGet = Process32Next(hSnapshot, &ppe);

}


CloseHandle(hSnapshot);


return ret_val;

}


* 사용법

int ret = FindDoubleProcess("aaa.exe", -1);

위처럼 해당파일명이 존재하는지 찾게 됩니다. 
대소문자를 구분하게 되어서 호출 시 소문자로 전달해야 정확히 찾게 됩니다.

참 쉽죠~~






+ Recent posts