CreateProcessA 함수(processthreadsapi.h)

새 프로세스와 해당 기본 스레드를 만듭니다. 새 프로세스는 호출 프로세스의 보안 컨텍스트에서 실행됩니다.

호출 프로세스가 다른 사용자를 가장하는 경우 새 프로세스는 가장 토큰이 아닌 호출 프로세스에 토큰을 사용합니다. 가장 토큰으로 표시되는 사용자의 보안 컨텍스트에서 새 프로세스를 실행하려면 CreateProcessAsUser 또는 CreateProcessWithLogonW 함수를 사용합니다.

구문

BOOL CreateProcessA(
  [in, optional]      LPCSTR                lpApplicationName,
  [in, out, optional] LPSTR                 lpCommandLine,
  [in, optional]      LPSECURITY_ATTRIBUTES lpProcessAttributes,
  [in, optional]      LPSECURITY_ATTRIBUTES lpThreadAttributes,
  [in]                BOOL                  bInheritHandles,
  [in]                DWORD                 dwCreationFlags,
  [in, optional]      LPVOID                lpEnvironment,
  [in, optional]      LPCSTR                lpCurrentDirectory,
  [in]                LPSTARTUPINFOA        lpStartupInfo,
  [out]               LPPROCESS_INFORMATION lpProcessInformation
);

매개 변수

[in, optional] lpApplicationName

실행할 모듈의 이름입니다. 이 모듈은 Windows 기반 애플리케이션일 수 있습니다. 로컬 컴퓨터에서 적절한 하위 시스템을 사용할 수 있는 경우 다른 유형의 모듈(예: MS-DOS 또는 OS/2)일 수 있습니다.

문자열은 실행할 모듈의 전체 경로 및 파일 이름을 지정하거나 부분 이름을 지정할 수 있습니다. 부분 이름의 경우 함수는 현재 드라이브와 현재 디렉터리를 사용하여 사양을 완료합니다. 함수는 검색 경로를 사용하지 않습니다. 이 매개 변수는 파일 이름 확장명을 포함해야 합니다. 기본 확장은 가정되지 않습니다.

lpApplicationName 매개 변수는 NULL일 수 있습니다. 이 경우 모듈 이름은 lpCommandLine 문자열의 첫 번째 공백으로 구분된 토큰이어야 합니다. 공백이 포함된 긴 파일 이름을 사용하는 경우 따옴표 붙은 문자열을 사용하여 파일 이름이 끝나고 인수가 시작되는 위치를 나타냅니다. 그렇지 않으면 파일 이름이 모호합니다. 예를 들어 문자열 "c:\program files\sub dir\program name"을 고려합니다. 이 문자열은 여러 가지 방법으로 해석할 수 있습니다. 시스템은 다음 순서로 가능성을 해석하려고 합니다.

  1. c:\program.exe
  2. c:\program files\sub.exe
  3. c:\program files\sub dir\program.exe
  4. c:\program files\sub dir\program name.exe

실행 모듈이 16비트 애플리케이션인 경우 lpApplicationNameNULL이어야 하며 lpCommandLine 에서 가리키는 문자열은 실행 가능한 모듈과 해당 인수를 지정해야 합니다.

일괄 처리 파일을 실행하려면 명령 인터프리터를 시작해야 합니다. lpApplicationName 을 cmd.exe 로 설정하고 lpCommandLine 을 다음 인수로 설정합니다. /c 및 일괄 처리 파일의 이름.

[in, out, optional] lpCommandLine

실행할 명령줄입니다.

이 문자열의 최대 길이는 유니코드 종료 null 문자를 포함하여 32,767자입니다. lpApplicationNameNULL인 경우 lpCommandLine의 모듈 이름 부분은 MAX_PATH 문자로 제한됩니다.

이 함수의 유니코드 버전인 CreateProcessW는 이 문자열의 내용을 수정할 수 있습니다. 따라서 이 매개 변수는 읽기 전용 메모리(예: const 변수 또는 리터럴 문자열)에 대한 포인터가 될 수 없습니다. 이 매개 변수가 상수 문자열인 경우 함수는 액세스 위반을 일으킬 수 있습니다.

lpCommandLine 매개 변수는 NULL일 수 있습니다. 이 경우 함수는 lpApplicationName 이 가리키는 문자열을 명령줄로 사용합니다.

lpApplicationNamelpCommandLine이 모두 NULL이 아닌 경우 lpApplicationName에서 가리키는 null로 끝나는 문자열은 실행할 모듈을 지정하고 lpCommandLine에서 가리키는 null로 끝나는 문자열은 명령줄을 지정합니다. 새 프로세스는 GetCommandLine 을 사용하여 전체 명령줄을 검색할 수 있습니다. C로 작성된 콘솔 프로세스는 argc 및 argv 인수 사용하여 명령줄을 구문 분석할 수 있습니다. argv[0]은 모듈 이름이기 때문에 C 프로그래머는 일반적으로 명령줄에서 모듈 이름을 첫 번째 토큰으로 반복합니다.

lpApplicationName이 NULL인 경우 명령줄의 첫 번째 공백으로 구분된 토큰은 모듈 이름을 지정합니다. 공백이 포함된 긴 파일 이름을 사용하는 경우 따옴표 붙은 문자열을 사용하여 파일 이름이 끝나고 인수가 시작되는 위치를 나타냅니다( lpApplicationName 매개 변수에 대한 설명 참조). 파일 이름에 확장명을 포함하지 않으면 .exe 추가됩니다. 따라서 파일 이름 확장명을 .com 경우 이 매개 변수에는 .com 확장명을 포함해야 합니다. 파일 이름이 확장명 없이 마침표(.)로 끝나거나 파일 이름에 경로가 포함된 경우 .exe 추가되지 않습니다. 파일 이름에 디렉터리 경로가 없는 경우 시스템은 다음 순서로 실행 파일을 검색합니다.

  1. 애플리케이션이 로드된 디렉터리입니다.
  2. 부모 프로세스의 현재 디렉터리입니다.
  3. 32비트 Windows 시스템 디렉터리입니다. GetSystemDirectory 함수를 사용하여 이 디렉터리의 경로를 가져옵니다.
  4. 16비트 Windows 시스템 디렉터리입니다. 이 디렉터리의 경로를 가져오는 함수는 없지만 검색됩니다. 이 디렉터리의 이름은 System입니다.
  5. Windows 디렉터리입니다. GetWindowsDirectory 함수를 사용하여 이 디렉터리의 경로를 가져옵니다.
  6. PATH 환경 변수에 나열된 디렉터리입니다. 이 함수는 App Paths 레지스트리 키로 지정된 애플리케이션별 경로를 검색하지 않습니다. 이 애플리케이션별 경로를 검색 순서에 포함하려면 ShellExecute 함수를 사용합니다.
시스템은 명령줄 문자열에 종료 null 문자를 추가하여 파일 이름을 인수와 분리합니다. 이렇게 하면 내부 처리를 위해 원래 문자열을 두 개의 문자열로 나눕니다.

[in, optional] lpProcessAttributes

새 프로세스 개체에 반환된 핸들을 자식 프로세스에서 상속할 수 있는지 여부를 결정하는 SECURITY_ATTRIBUTES 구조체에 대한 포인터입니다. lpProcessAttributesNULL이면 핸들을 상속할 수 없습니다.

구조체의 lpSecurityDescriptor 멤버는 새 프로세스에 대한 보안 설명자를 지정합니다. lpProcessAttributes가 NULL이거나 lpSecurityDescriptorNULL인 경우 프로세스는 기본 보안 설명자를 가져옵니다. 프로세스에 대한 기본 보안 설명자의 ACL은 작성자의 기본 토큰에서 가져옵니다. Windows XP: 프로세스에 대한 기본 보안 설명자의 ACL은 작성자의 기본 또는 가장 토큰에서 가져옵니다. 이 동작은 WINDOWS XP SP2 및 Windows Server 2003에서 변경되었습니다.

[in, optional] lpThreadAttributes

새 스레드 개체에 반환된 핸들을 자식 프로세스에서 상속할 수 있는지 여부를 결정하는 SECURITY_ATTRIBUTES 구조체에 대한 포인터입니다. lpThreadAttributes가 NULL이면 핸들을 상속할 수 없습니다.

구조체의 lpSecurityDescriptor 멤버는 기본 스레드에 대한 보안 설명자를 지정합니다. lpThreadAttributes가 NULL이거나 lpSecurityDescriptor가 NULL인 경우 스레드는 기본 보안 설명자를 가져옵니다. 스레드에 대한 기본 보안 설명자의 ACL은 프로세스 토큰에서 가져옵니다. Windows XP: 스레드에 대한 기본 보안 설명자의 ACL은 작성자의 기본 또는 가장 토큰에서 가져옵니다. 이 동작은 WINDOWS XP SP2 및 Windows Server 2003에서 변경되었습니다.

[in] bInheritHandles

이 매개 변수가 TRUE이면 호출 프로세스의 상속 가능한 각 핸들은 새 프로세스에서 상속됩니다. 매개 변수가 FALSE이면 핸들이 상속되지 않습니다. 상속된 핸들은 원래 핸들과 동일한 값 및 액세스 권한을 갖습니다. 상속 가능한 핸들에 대한 추가 설명은 비고를 참조하세요.

터미널 서비스: 세션 간에 핸들을 상속할 수 없습니다. 또한 이 매개 변수가 TRUE이면 호출자와 동일한 세션에서 프로세스를 만들어야 합니다.

PPL(Protected Process Light) 프로세스: PPL이 아닌 프로세스에서 PPL 프로세스로 PROCESS_DUP_HANDLE 허용되지 않으므로 PPL 프로세스가 PPL이 아닌 프로세스를 만들 때 제네릭 핸들 상속이 차단됩니다. 프로세스 보안 및 액세스 권한 참조

Windows 7: 매개 변수가 FALSE인 경우에도 STD_INPUT_HANDLE, STD_OUTPUT_HANDLE 및 STD_ERROR_HANDLE 상속됩니다.

[in] dwCreationFlags

우선 순위 클래스 및 프로세스 만들기를 제어하는 플래그입니다. 값 목록은 프로세스 만들기 플래그를 참조하세요.

또한 이 매개 변수는 프로세스 스레드의 일정 우선 순위를 결정하는 데 사용되는 새 프로세스의 우선 순위 클래스를 제어합니다. 값 목록은 GetPriorityClass를 참조하세요. 우선 순위 클래스 플래그를 지정하지 않으면 만들기 프로세스의 우선 순위 클래스가 IDLE_PRIORITY_CLASS 또는 BELOW_NORMAL_PRIORITY_CLASS 않는 한 우선 순위 클래스는 기본적으로 NORMAL_PRIORITY_CLASS. 이 경우 자식 프로세스는 호출 프로세스의 기본 우선 순위 클래스를 받습니다.

dwCreationFlags 매개 변수의 값이 0인 경우:

  • 이 프로세스는 호출자와 부모 콘솔의 오류 모드를 모두 상속합니다.
  • 새 프로세스에 대한 환경 블록은 ANSI 문자를 포함하는 것으로 간주됩니다(추가 정보는 lpEnvironment 매개 변수 참조).
  • 16비트 Windows 기반 애플리케이션은 공유 VDM(Virtual DOS 머신)에서 실행됩니다.

[in, optional] lpEnvironment

새 프로세스의 환경 블록에 대한 포인터입니다. 이 매개 변수가 NULL인 경우 새 프로세스는 호출 프로세스의 환경을 사용합니다.

환경 블록은 null로 끝나는 null 종료 문자열 블록으로 구성됩니다. 각 문자열은 다음과 같은 형식입니다.

이름=value\0

등호는 구분 기호로 사용되므로 환경 변수의 이름에 사용하면 안 됩니다.

환경 블록에는 유니코드 또는 ANSI 문자가 포함될 수 있습니다. lpEnvironment가 가리키는 환경 블록에 유니코드 문자가 포함된 경우 dwCreationFlagsCREATE_UNICODE_ENVIRONMENT 포함되어 있는지 확인합니다.

이 함수의 ANSI 버전 인 CreateProcessA 는 프로세스에 대한 환경 블록의 총 크기가 32,767자를 초과하면 실패합니다.

ANSI 환경 블록은 두 개의 0바이트로 종료됩니다. 하나는 마지막 문자열에 대해 하나씩, 다른 하나는 블록을 종료합니다. 유니코드 환경 블록은 4개의 0바이트로 종료됩니다. 마지막 문자열의 경우 2개, 블록을 종료하려면 2바이트가 더 종료됩니다.

[in, optional] lpCurrentDirectory

프로세스의 현재 디렉터리에 대한 전체 경로입니다. 문자열은 UNC 경로를 지정할 수도 있습니다.

이 매개 변수가 NULL인 경우 새 프로세스는 호출 프로세스와 동일한 현재 드라이브 및 디렉터리를 갖습니다. (이 기능은 주로 애플리케이션을 시작하고 초기 드라이브 및 작업 디렉터리를 지정해야 하는 셸용으로 제공됩니다.)

[in] lpStartupInfo

STARTUPINFO 또는 STARTUPINFOEX 구조체에 대한 포인터입니다.

확장 특성을 설정하려면 STARTUPINFOEX 구조를 사용하고 dwCreationFlags 매개 변수에 EXTENDED_STARTUPINFO_PRESENT 지정합니다.

STARTUPINFO 또는 STARTUPINFOEX의 핸들은 더 이상 필요하지 않은 경우 CloseHandle을 사용하여 닫아야 합니다.

중요 호출자는 STARTUPINFO 의 표준 핸들 필드에 유효한 핸들 값이 포함되도록 합니다. 이러한 필드는 dwFlags 멤버가 STARTF_USESTDHANDLES 지정하는 경우에도 유효성 검사 없이 자식 프로세스에 변경되지 않고 복사됩니다. 값이 잘못되면 자식 프로세스가 잘못 작동하거나 충돌할 수 있습니다. 애플리케이션 검증 도구 런타임 확인 도구를 사용하여 잘못된 핸들을 검색합니다.
 

[out] lpProcessInformation

새 프로세스에 대한 식별 정보를 수신하는 PROCESS_INFORMATION 구조체에 대한 포인터입니다.

PROCESS_INFORMATION 핸들은 더 이상 필요하지 않은 경우 CloseHandle을 사용하여 닫아야 합니다.

반환 값

함수가 성공하면 반환 값이 0이 아닙니다.

함수가 실패하면 반환 값은 0입니다. 확장 오류 정보를 가져오려면 GetLastError를 호출합니다.

프로세스 초기화가 완료되기 전에 함수가 반환됩니다. 필요한 DLL을 배치할 수 없거나 초기화에 실패하면 프로세스가 종료됩니다. 프로세스의 종료 상태 얻으려면 GetExitCodeProcess를 호출합니다.

설명

프로세스에 프로세스 식별자가 할당됩니다. 식별자는 프로세스가 종료될 때까지 유효합니다. 프로세스를 식별하는 데 사용하거나 OpenProcess 함수에 지정하여 프로세스에 대한 핸들을 열 수 있습니다. 프로세스의 초기 스레드에도 스레드 식별자가 할당됩니다. OpenThread 함수에 지정하여 스레드에 대한 핸들을 열 수 있습니다. 식별자는 스레드가 종료될 때까지 유효하며 시스템 내에서 스레드를 고유하게 식별하는 데 사용할 수 있습니다. 이러한 식별자는 PROCESS_INFORMATION 구조에서 반환됩니다.

운영 체제가 프로세스에 제공하는 명령줄의 실행 파일 이름이 호출 프로세스가 CreateProcess 함수에 제공하는 명령줄의 실행 파일 이름과 반드시 동일하지는 않습니다. 운영 체제는 정규화된 경로 없이 제공되는 실행 파일 이름 앞에 정규화된 경로를 추가할 수 있습니다.

호출 스레드는 WaitForInputIdle 함수를 사용하여 새 프로세스가 초기화를 완료하고 입력이 보류되지 않은 사용자 입력을 대기할 때까지 기다릴 수 있습니다. CreateProcess는 새 프로세스가 초기화를 완료할 때까지 기다리지 않고 반환되므로 부모 프로세스와 자식 프로세스 간의 동기화에 유용할 수 있습니다. 예를 들어 만들기 프로세스는 새 프로세스와 연결된 창을 찾기 전에 WaitForInputIdle 을 사용합니다.

프로세스를 종료하는 기본 방법은 ExitProcess 함수를 사용하는 것입니다. 이 함수는 프로세스에 연결된 모든 DLL에 종료에 근접하는 알림을 보내기 때문입니다. 프로세스를 종료하는 다른 수단은 연결된 DLL에 알리지 않습니다. 스레드가 ExitProcess를 호출하면 추가 코드(연결된 DLL의 스레드 종료 코드 포함)를 실행할 기회 없이 프로세스의 다른 스레드가 종료됩니다. 자세한 내용은 프로세스 종료를 참조하세요.

부모 프로세스는 프로세스를 만드는 동안 자식 프로세스의 환경 변수를 직접 변경할 수 있습니다. 이는 프로세스가 다른 프로세스의 환경 설정을 직접 변경할 수 있는 유일한 상황입니다. 자세한 내용은 환경 변수 변경을 참조하세요.

애플리케이션이 환경 블록을 제공하는 경우 시스템 드라이브의 현재 디렉터리 정보는 새 프로세스로 자동으로 전파되지 않습니다. 예를 들어 =C: 라는 환경 변수가 있습니다. 해당 값은 C 드라이브의 현재 디렉터리입니다. 애플리케이션은 현재 디렉터리 정보를 새 프로세스에 수동으로 전달해야 합니다. 이렇게 하려면 애플리케이션에서 이러한 환경 변수 문자열을 명시적으로 만들고, 사전순으로 정렬하고(시스템이 정렬된 환경을 사용하기 때문에) 환경 블록에 배치해야 합니다. 일반적으로 환경 블록 정렬 순서로 인해 환경 블록의 맨 앞으로 이동합니다.

드라이브 X에 대한 현재 디렉터리 정보를 가져오는 한 가지 방법은 를 호출 GetFullPathName("X:", ...)하는 것입니다. 따라서 애플리케이션이 환경 블록을 검사하지 않아도 됩니다. 반환된 전체 경로가 X:인 경우 루트 디렉터리가 새 프로세스의 드라이브 X에 대한 기본 현재 디렉터리이므로 해당 값을 환경 데이터로 전달할 필요가 없습니다.

CREATE_NEW_PROCESS_GROUP 지정한 프로세스를 만들면 새 프로세스를 대신하여 SetConsoleCtrlHandler(NULL,TRUE)에 대한 암시적 호출이 수행됩니다. 즉, 새 프로세스에서 Ctrl+C를 사용하지 않도록 설정했습니다. 이렇게 하면 셸이 Ctrl+C 자체를 처리하고 해당 신호를 하위 프로세스에 선택적으로 전달할 수 있습니다. Ctrl+BREAK는 사용하지 않도록 설정되지 않으며 프로세스/프로세스 그룹을 중단하는 데 사용할 수 있습니다.

기본적으로 TRUEbInheritHandles 매개 변수 값으로 전달하면 모든 상속 가능한 핸들이 새 프로세스에서 상속됩니다. 이는 여러 스레드에서 동시에 프로세스를 만들면서도 각 프로세스가 서로 다른 핸들을 상속하기를 원하는 애플리케이션에 문제가 될 수 있습니다. 애플리케이션은 PROC_THREAD_ATTRIBUTE_HANDLE_LIST 매개 변수와 함께 UpdateProcThreadAttributeList 함수를 사용하여 특정 프로세스에서 상속할 핸들 목록을 제공할 수 있습니다.

보안 설명

첫 번째 매개 변수 인 lpApplicationNameNULL일 수 있습니다. 이 경우 실행 파일 이름은 lpCommandLine이 가리키는 공백으로 구분된 문자열에 있어야 합니다. 실행 파일 또는 경로 이름에 공백이 있는 경우 함수가 공백을 구문 분석하는 방식으로 인해 다른 실행 파일이 실행될 위험이 있습니다. 다음 예제는 함수가 "MyApp.exe" 대신 "Program.exe"(있는 경우)을 실행하려고 하기 때문에 위험합니다.
	LPTSTR szCmdline = _tcsdup(TEXT("C:\\Program Files\\MyApp -L -S"));
	CreateProcess(NULL, szCmdline, /* ... */);

악의적인 사용자가 시스템에서 "Program.exe"이라는 애플리케이션을 만드는 경우 Program Files 디렉터리를 사용하여 CreateProcess 를 잘못 호출하는 모든 프로그램은 의도한 애플리케이션 대신 이 애플리케이션을 실행합니다.

이 문제를 방지하려면 lpApplicationName대해 NULL을 전달하지 마세요. lpApplicationName대해 NULL을 전달하는 경우 아래 예제와 같이 lpCommandLine의 실행 경로 주위에 따옴표를 사용합니다.

	LPTSTR szCmdline[] = _tcsdup(TEXT("\"C:\\Program Files\\MyApp\" -L -S"));
	CreateProcess(NULL, szCmdline, /*...*/);

예제

예제는 프로세스 만들기를 참조하세요.

참고

processthreadsapi.h 헤더는 CREATEProcess를 유니코드 전처리기 상수의 정의에 따라 이 함수의 ANSI 또는 유니코드 버전을 자동으로 선택하는 별칭으로 정의합니다. 인코딩 중립 별칭을 인코딩 중립이 아닌 코드와 혼합하면 컴파일 또는 런타임 오류가 발생하는 불일치가 발생할 수 있습니다. 자세한 내용은 함수 프로토타입에 대한 규칙을 참조하세요.

요구 사항

요구 사항
지원되는 최소 클라이언트 Windows XP [데스크톱 앱 | UWP 앱]
지원되는 최소 서버 Windows Server 2003 [데스크톱 앱 | UWP 앱]
대상 플랫폼 Windows
헤더 processthreadsapi.h(Windows Server 2003, Windows Vista, Windows 7, Windows Server 2008 Windows Server 2008 R2에 Windows.h 포함)
라이브러리 Kernel32.lib
DLL Kernel32.dll

참고 항목

CloseHandle

ShellExecuteA

CreateProcessAsUser

CreateProcessWithLogonW

ExitProcess

GetCommandLine

GetEnvironmentStrings

GetExitCodeProcess

GetFullPathName

GetStartupInfo

OpenProcess

PROCESS_INFORMATION

프로세스 및 스레드 함수

프로세스

SECURITY_ATTRIBUTES

STARTUPINFO

STARTUPINFOEX

SetErrorMode

TerminateProcess

WaitForInputIdle