typedef struct _STARTUPINFO {
DWORD cb; // 구조체의 변수의 크기(byte)를 전달
LPTSTR lpReserved; //
LPTSTR lpDesktop; // 어플리케이션 동작시 바탕화면 이름 대체(NULL이면 현재 데스크탑)
LPTSTR lpTitle; // 타이틀 바 제목 (NULL이면 프로세스의 파일명이 타이틀이 됨)
DWORD dwX; // 시작될 프로세스 윈도우 x좌표
DWORD dwY; // 시작될 프로세스 윈도우 y좌표
DWORD dwXSize; /* 윈도우 가로 길이, 세로 길이
DWORD dwYSize; 지정하지 않으면 CW_USEDEFAULT로 실행 */
DWORD dwXCountChars; /* 콘솔 어플리케이션이 실행 중이다가 자식프로세스 생성시
DWORD dwYCountChars; 자식 프로세스 x,y 너비를 지정*/
DWORD dwFillAttribute; // 백그라운드 색깔 설정
DWORD dwFlags; // 실행될 프로세스에 지정할 플래그
/*
STARTF_FORCEONFEEDBACK : 프로세스 수행 상태에 따라 마우스 커서 변경
STARTF_FORCEOFFEEDBACK : 프로세스가 실행되고 2초동안 마우스 커서가 모래시계(?) 상태
STARTF_PREVENTPINNING : 작업 표시줄에 표시되지 않는 프로세스 생성
STARTF_RUNFULLSCREEN : 전체화면으로 시작
STARTF_TITLEISAPPID : lpTitle 파라미터의 값이 작업표시줄과 시작 메뉴의 이름이 됨
+ STARTF_TITLEISLINKNAME과 같이 사용될 수 없음
STARTF_TITLEISLINKNAME : lpTitle 파라미터(프로세스 이름)가 단축 아이콘의 이름이 됨
+ STARTF_TITLEISAPPID와 같이 사용될 수 없음
STARTF_USECOUNTCHARS : dwXCountChars, dwYCountChars 파라미터를 사용
STARTF_USEPOSITION : dwX, dwY 파라미터를 사용
STARTF_USEFILLATTRIBUTE : dwFillAttributes 파라미터를 사용
STARTF_USEHOTKEY : hStdInput 파라미터를 사용
+ STARTF_USESTDHANDLES와 같이 사용될 수 없음
STARTF_USESHOWWINDOW : wShowWindow 파라미터를 사용
- STARTF_USESIZE : dwXSize, dwYSize 파라미터를 사용
- STARTF_USESTDHANDLES : hStdInput, hStdOutput, hStdError 파라미터를 사용
+ STARTF_USEHOTKEY와 같이 사용될 수 없음
*/
WORD wShowWindow; // CUI인지 혹은 GUI인지 설정
WORD cbReserved2; // 0으로 초기화해서 사용(사용되지 않음)
LPBYTE lpReserved2; // NULL초기화 (사용되지 않음)
HANDLE hStdInput; // 콘솔 입출력에 사용할 버퍼 핸들
HANDLE hStdOutput; // 키보드 입력 버퍼
HANDLE hStdError; // 윈도우 화면 출력 버퍼
} STARTUPINFO, *LPSTARTUPINFO;
typedef struct _PROCESS_INFORMATION {
HANDLE hProcess; // 프로세스 핸들
HANDLE hThread; // 쓰레드 핸들
DWORD dwProcessId; // 프로세스 id
DWORD dwThreadId; // 쓰레드 id
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;
/*
Process A -------> Process B
(부모 프로세스) CreateProcess (자식 프로세스)
*/
BOOL CreateProcess(
LPCTSTR lpApplicationName, // 생성될 프로세스의 이름
LPTSTR lpCommandLine, // 생성될 프로세스에 인자 전달(변수만 가능)
LPSECURITY_ATTRIBUTES lpProcessAttributes, // 프로세스의 보안 속성 지정
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 쓰레드의 보안 속성 지정
BOOL bInheritHandles, // TRUE : 부모 프로세스가 소유하는 상속 가능한 핸들을 상속한다.
DWORD dwCreationFlags, // 생성하는 프로세스의 특성을 결정짓는 옵션(우선순위)
LPVOID lpEnvironment, // 생성하는 프로세스의 Environment Block 지정 NULL : 부모 프로세스의 환경 블록 복사
LPCTSTR lpCurrentDirectory, // 생성하는 프로세스의 현재 디렉터리 설정 NULL : 부모 프로세스의 현재 디렉터리
LPSTARTUPINFO lpStartupInfo, // STARTUPINFO 구조체 변수 초기화한 후 변수의 포인터를 인자로 전달
LPPROCESS_INFORMATION lpProcessInformation //생성하는 프로세스의 정보를 얻기 위한 인자
//PROCESS_INFORMATION 구조체 변수의 주소값을 인자로 전달
);
BOOL CUtil::RunProcess(CString RunFilePath, int show)
{
// STARTUPINFO 생성하는 프로세스의 속성을 지정할 때 사용하는 구조체
STARTUPINFO si;
// 새로 생선된 프로세스와 스레드 정보가 있음
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
si.lpReserved = NULL;
si.lpReserved2 = NULL;
si.cbReserved2 = 0;
si.lpDesktop = NULL;
si.lpTitle = NULL;
si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
si.dwX = 0;
si.dwY = 0;
si.dwFillAttribute = 0;
si.wShowWindow = show;
CreateProcess(NULL,RunFilePath.GetBuffer(0),NULL,NULL,TRUE, NULL,NULL,NULL,&si,&pi);
// WaitForSingleObject(pi.hProcess, INFINITE);
// 핸들 닫기
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return TRUE;
}
// 시스템 주소 공간에 상주하는 프로세스 목록 스냅샷으로 가져올때 엔트리를 설명
typedef struct tagPROCESSENTRY32 {
DWORD dwSize; // 구조체 크기(byte)
DWORD cntUsage; // 사용안함 0으로 설정
DWORD th32ProcessID; // 프로세스 ID
ULONG_PTR th32DefaultHeapID; // 사용안함 0으로 설정
DWORD th32ModuleID; // 사용안함 0으로 설정
DWORD cntThreads; // 프로세스가 시작한 스레드 실행 수
DWORD th32ParentProcessID; // 프로세스(부모 프로세스)가 생성한 프로세스 ID
LONG pcPriClassBase; // 프로세스가 생성한 모든 스레드 기본 우선순위
DWORD dwFlags; // 사용안함 0으로 설정
TCHAR szExeFile[MAX_PATH]; // 프로세스 실행 파일 이름
} PROCESSENTRY32, *PPROCESSENTRY32;
HANDLE OpenProcess(
DWORD dwDesiredAccess, // 프로세스 접근 권한
BOOL bInheritHandle, // True면 프로세스가 상속에 의해 프로세스 생성, False 상속 안함
DWORD dwProcessId // 오픈할 로컬 프로세스 ID
);
프로세스 지정 접근 권한
값 | 의미 |
PROCESS_ALL_ACCESS | 프로세스 오브젝트에 대한 모든 가능한 접근 권한 |
PROCESS_CREATE_PROCESS (0x0080) | 프로세스를 생성하기 위해 필요 |
PROCESS_CREATE_THREAD (0x0002) | 스레드를 생성하기 위해 필요 |
PROCESS_DUP_HANDLE (0x0040) | DuplicateHandle을 사용하여 핸들을 복사하기 위해 필요 |
PROCESS_QUERY_INFORMATION (0x0400) | (see OpenProcessToken). 토큰, 종료 코드 및 우선 순위 클래스와 같은 프로세스에 대한 특정 정보를 검색하는 데 필요함 |
PROCESS_QUERY_LIMITED_INFORMATION(0x1000) | (see GetExitCodeProcess, GetPriorityClass, IsProcessInJob, QueryFullProcessImageName). 프로세스 특정 정보를 탐색시 필요 |
PROCESS_SET_INFORMATION (0x0200) | (see SetPriorityClass). 우선순위 클래스와 같은 특정 프로세스 정보에 대한 설정시 필요 |
PROCESS_SET_QUOTA (0x0100) | SetProcessWorkingSetSize. 사용 메모리 제한 설정시 필요 |
PROCESS_SUSPEND_RESUME (0x0800) | 프로세스를 재시작하거나 일시정시 필요 |
PROCESS_TERMINATE (0x0001) | TerminateProcess. 사용 프로세스 제거시 필요 |
PROCESS_VM_OPERATION (0x0008) | (see VirtualProtectEx and WriteProcessMemory). 프로세스 주소 공간에서 작동 수행 필요 |
PROCESS_VM_READ (0x0010) | ReadProcessMemory.사용하는 프로세스에서 메모리르 읽기 필요 |
PROCESS_VM_WRITE (0x0020) | WriteProcessMemory.사용하는 프로세스에서 메모리에 쓰기 필요 |
SYNCHRONIZE(0x00100000L) | wait functions 를 사용하여 프로세스 종료를 기다리는데 필요 |
BOOL CUtil::KillProcess(CString ProcessName)
{
BOOL b = FALSE;
HANDLE hSnapshot = NULL;
PROCESSENTRY32 pe32 = {0};
// 시스템 프로세서의 상태(힙, 모듈, 스레드)를 읽어 온다.
// 성공하면 스냅샷에 대한 핸들을 반환하고, 실패하면 INVALID_HANDLE_VALUE를 반환한다.
hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
// 엔트리 구조체 사이즈
pe32.dwSize = sizeof( PROCESSENTRY32 );
// 엔트리에서 구성된 자료구조 가져오기
if( Process32First( hSnapshot , &pe32 ) )
{
do
{
// printf("%20s", pe32.szExeFile);
if(ProcessName.Compare(pe32.szExeFile) == 0)
// if(strcmp(pe32.szExeFile, ProcessName) == 0)
{
b = TRUE;
printf("Process Found = %20s !!!\n", pe32.szExeFile);
//AfxMessageBox("Found Process");
HANDLE hProcess = OpenProcess( PROCESS_TERMINATE , FALSE, pe32.th32ProcessID );
if( hProcess )
{
DWORD dwExitCode;
/* BOOL WINAPI GetExitCodeProcess
( _In_ HANDLE hProcess, _Out_ LPDWORD lpExitCode )
hProcess : 종료 코드를 받기 원하는 프로세스의 핸들
PROCESS_QUERY_INFORMATION 또는 PROCESS_QUERY_LIMITED_INFORMATION
권한이 있어야 함.
lpExitCode : 프로세스 종료 상태를 받을 변수에 대한 포인터
실패시 0을 반환*/
GetExitCodeProcess( hProcess, &dwExitCode);
/* BOOL WINAPI TerminateProcess
(_In_ HANDLE hProcess, _In_ uExitCode)
hProcess : 종료할 프로세스의 핸들을 설정
핸들의 접근 권한은 반드시 PROCESS_TERMINATE를 가져야 함.
uExitCode : 프로세스 종료 코드를 설정
통상적으로 정상 종료 인경우 0을 비정상 종료인경우 -1을 입력*/
TerminateProcess( hProcess, dwExitCode);
CloseHandle(hProcess);
//return TRUE;
}
}
} while ( Process32Next( hSnapshot , &pe32 ) );
}
else
{
printf("???\n");
}
CloseHandle (hSnapshot );
return b;
}
TerminateProcess 함수는
Jeffery Richter 의 Programming Application for Win2k나 기타
이와 관련된 책에서는 되도록 쓰지 말도록 권고하고 있는데
리소스가 정리되지 않고 바로 죽기 때문이다.
그래서 ExitProcess라는 함수를 사용해서
그프로세스가 스스로 죽도록 해야한다.
BOOL CUtil::KillProcessPid(int pid)
{
BOOL b = FALSE;
HANDLE hSnapshot = NULL;
PROCESSENTRY32 pe32 = {0};
hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
pe32.dwSize = sizeof( PROCESSENTRY32 );
if( Process32First( hSnapshot , &pe32 ) )
{
do
{
//printf("%20s", pe32.szExeFile);
if(pe32.th32ProcessID == pid)
// if(strcmp(pe32.szExeFile, ProcessName) == 0)
{
b = TRUE;
printf("Process Found = %20s !!!\n", pe32.szExeFile);
//AfxMessageBox("Found Process");
HANDLE hProcess = OpenProcess( PROCESS_TERMINATE , FALSE, pe32.th32ProcessID );
if( hProcess )
{
DWORD dwExitCode;
GetExitCodeProcess( hProcess, &dwExitCode);
TerminateProcess( hProcess, dwExitCode);
CloseHandle(hProcess);
//return TRUE;
}
}
} while ( Process32Next( hSnapshot , &pe32 ) );
}
else
{
printf("???\n");
}
CloseHandle (hSnapshot );
return b;
}
// 프로세스 이름으로 PID 찾기
int CUtil::GetStatusProcess(char *pName)
{
int Pid = 0;
BOOL b = FALSE;
HANDLE hProcess = NULL;
PROCESSENTRY32 pe32 = {0};
hProcess = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
pe32.dwSize = sizeof( PROCESSENTRY32 );
// 시스템 스냅샷에 처음 발생한 프로세스에 대한 정보 검색
if( Process32First( hProcess, &pe32 ) )
{
do
{
printf("%20s", pe32.szExeFile);
if(strcmp(pe32.szExeFile, pName) == 0)
{
b = TRUE;
printf("Process Found = %20s !!!", pe32.szExeFile);
Pid = pe32.th32ProcessID;
break;
//AfxMessageBox("Found Process");
}
} while ( Process32Next( hProcess, &pe32 ) );
}
else
{
printf("???\n");
}
CloseHandle (hProcess);
return Pid;
}
'개발 > VC++' 카테고리의 다른 글
[스크랩] C++ 커널 오브젝트 타입/네임 구하기 (0) | 2021.07.19 |
---|---|
[스크랩] Kernel object 와 오브젝트 핸 (0) | 2021.07.19 |
[스크랩] 쓰레드란? (0) | 2021.07.07 |
[스크랩] C++ 스레드 thread (0) | 2021.06.29 |
MFC 흐름도 (0) | 2015.03.25 |