CreateProcess 함수를 통해 프로세스를 생성해보자
processthreadsapi.h 헤더는 CreateProcess를 UNICODE 전처리기 상수의 정의에 따라,
이 함수의 ANSI 또는 UNICODE 버전을 자동으로 선택하는 별칭으로 정의하고 있다
(ANSI : CreateProcessA / UNICODE : CreateProcessW)
CreateProcess 함수를 호출하는 프로세스를 부모 프로세스 (Parent Process),
CreateProcess 함수 호출에 의해 생성된 프로세스를 자식 프로세스 (Child Process) 라 한다
함수 선언 형태
BOOL CreateProcess(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
1. lpApplicationName
- 생성할 프로세스의 실행파일 이름 및 확장자
- 경로명 추가 지정 가능
- 경로명을 지정하지 않을 경우 프로그램의 현재 디렉토리 (Current Directory) 기준
- NULL 인 경우 lpCommandLine 의 첫 번째 토큰으로 실행파일 이름을 전달
2. lpCommandLine
- 새로 생성하는 프로세스에 전달할 인자 (변경 가능한 문자열)
- lpApplicationName 이 NULL 인 경우
- 실행파일의 이름을 첫 번째 토큰으로 전달 (최대 길이는 MAX_PATH 로 제한)
- 실행파일 검색 순서 (표준 검색경로)
- (1) 실행 중인 프로세스의 실행파일이 존재하는 디렉토리
- (2) 실행 중인 프로세스의 현재 디렉토리 (Current Directory)
- (3) Windows 의 시스템 디렉토리 (System Directory)
- (4) Windows 디렉토리 (Windows Directory)
- (5) 환경변수 PATH 에 의해 지정되어 있는 디렉토리
3. lpProcessAttributes
- 프로세스의 보안 속성 지정
- NULL 인 경우 Default 보안 속성 지정
4. lpThreadAttributes
- 쓰레드의 보안 속성 지정
- NULL 인 경우 Default 보안 속성 지정
5. bInheritHandles
- TRUE 인 경우 부모 프로세스 소유 핸들 중 상속 가능한 핸들 상속
6. dwCreationFlags
- 생성하는 프로세스의 특성 (특히 우선순위) 설정
- 미설정 시 0
7. lpEnvironment
- 프로세스마다 Environment Block (환경 블록) 이라는 메모리 블록 관리
- 프로세스가 실행에 필요로 하는 문자열을 저장
- 생성하는 프로세스의 환경 블록을 설정
- NULL 인 경우 부모 프로세스의 환경 블록 문자열 복사
8. lpCurrentDirectory
- 생성하는 프로세스의 현재 디렉토리 (Current Directory) 설정
- 디렉토리 정보를 포함하는 완전 경로 형태로 구성
- NULL 인 경우 부모 프로세스와 동일하게 설정
9. lpStartupInfo
- STARTUPINFO 구조체 변수를 초기화 후 주소값 전달
- 생성하는 프로세스의 속성 설정
10. lpProcessInformation
- 생성하는 프로세스 정보를 획득
- PROCESS_INFORMATION 구조체 변수의 주소값 전달
- 해당 변수에 프로세스 정보 저장
STARTUPINFO 구조체 정의
processthreadsapi.h 헤더는 STARTUPINFO를 UNICODE 전처리기 상수의 정의에 따라,
이 함수의 ANSI 또는 UNICODE 버전을 자동으로 선택하는 별칭으로 정의
(ANSI : STARTUPINFOA / UNICODE : STARTUPINFOW)
구조체 선언 형태
typedef struct _STARTUPINFO {
DWORD cb; // 바이트 단위 구조체 변수 크기
LPTSTR lpReserved;
LPTSTR lpDesktop;
LPTSTR lpTitle;
DWORD dwX; // 프로세스 윈도우 x 좌표
DWORD dwY; // 프로세스 윈도우 y 좌표
DWORD dwXSize; // 프로세스 윈도우 가로 길이
DWORD dwYSize; // 프로세스 윈도우 세로 길이
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags; // 설정된 멤버의 정보
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFO, *LPSTARTUPINFO;
PROCESS_INFORMATION 구조체 정의
새로 생성한 프로세스 및 기본 스레드에 대한 정보 저장
구조체 선언 형태
typedef struct _PROCESS_INFORMATION {
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
프로세스 생성 (Child 코드 링크, Parent 코드 링크)
// Child Process
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
int _tmain(int argc, TCHAR* argv[])
{
_tprintf(_T("%s\n"), argv[1]);
TCHAR temp;
_tscanf_s(_T("%c"), &temp, (unsigned int)sizeof(temp));
return 0;
}
// Parent Process
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
int _tmain(int argc, TCHAR* argv[])
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
SecureZeroMemory(&si, sizeof(si));
SecureZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
si.dwX = 100;
si.dwY = 200;
si.dwXSize = 300;
si.dwYSize = 200;
si.dwFlags = STARTF_USEPOSITION | STARTF_USESIZE;
TCHAR commandLine[] = _T("ChildProcess.exe CreateProcess");
if (!CreateProcess(
NULL,
commandLine,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi))
{
printf("CreateProcess failed (%d).\n", GetLastError());
return -1;
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
STARTUPINFO 구조체와 PROCESS_INFORMATION 구조체를 선언 후 0으로 초기화한다
컴파일러 최적화로 인해 ZeroMemory 함수 호출이 제거되지 않도록 SecureZeroMemory 사용을 권장한다
cb 는 STARTUPINFO 구조체의 바이트 단위 크기로 설정되어야 한다
이 외 멤버들을 통해 프로세스 윈도우의 위치나 크기 등에 대한 정보를 설정한다
commandLine 은 생성할 프로세스 실행파일의 이름과 전달 인자가 포함된 문자열이다
lpApplicationName 이 NULL 이므로 첫 번째 토큰으로 실행 파일의 이름이 포함되어야 한다
CreateProcess 함수를 호출한다
lpApplicationName 이 NULL 이므로 표준 검색경로 순서로 실행파일을 검색한다
ChildProcess.exe 를 실행하면서 CreateProcess 라는 인자를 전달한다
dwCreationFlags 가 CREATE_NEW_CONSOLE 이므로 새로운 콘솔 윈도우에서 실행된다
CreateProcess 함수는 프로세스 생성 실패 시 0을 반환한다
이 경우 오류 코드를 출력하고 종료한다
만약 프로세스 생성에 실패한다면, ChildProcess.exe 실행파일이 표준 검색경로 내에 존재하는지 확인하자
표준 검색경로는 다음 글에서 확인할 수 있다
https://pharan.tistory.com/entry/%ED%91%9C%EC%A4%80-%EA%B2%80%EC%83%89%EA%B2%BD%EB%A1%9C
참고 자료
https://learn.microsoft.com/ko-kr/windows/win32/procthread/creating-processes
https://learn.microsoft.com/ko-kr/previous-versions/windows/desktop/legacy/aa366920(v=vs.85)
https://learn.microsoft.com/ko-kr/previous-versions/windows/desktop/legacy/aa366877(v=vs.85)
https://www.youtube.com/playlist?list=PLVsNizTWUw7E2KrfnsyEjTqo-6uKiQoxc
'Windows' 카테고리의 다른 글
커널 오브젝트와 핸들 (0) | 2024.04.26 |
---|---|
표준 검색경로 (0) | 2024.04.11 |
오류 확인 (0) | 2024.04.09 |
64비트 기반 프로그래밍 (0) | 2024.04.03 |
MBCS / WBCS 동시 지원 (0) | 2024.04.02 |