Функция CreateProcessW (processthreadsapi.h)
Создает новый процесс и его основной поток. Новый процесс выполняется в контексте безопасности вызывающего процесса.
Если вызывающий процесс олицетворяет другого пользователя, новый процесс использует маркер для вызывающего процесса, а не маркер олицетворения. Чтобы запустить новый процесс в контексте безопасности пользователя, представленного маркером олицетворения, используйте функцию CreateProcessAsUser или CreateProcessWithLogonW.
Синтаксис
BOOL CreateProcessW(
[in, optional] LPCWSTR lpApplicationName,
[in, out, optional] LPWSTR lpCommandLine,
[in, optional] LPSECURITY_ATTRIBUTES lpProcessAttributes,
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] BOOL bInheritHandles,
[in] DWORD dwCreationFlags,
[in, optional] LPVOID lpEnvironment,
[in, optional] LPCWSTR lpCurrentDirectory,
[in] LPSTARTUPINFOW lpStartupInfo,
[out] LPPROCESS_INFORMATION lpProcessInformation
);
Параметры
[in, optional] lpApplicationName
Имя выполняемого модуля. Этот модуль может быть приложением на основе Windows. Он может быть другим типом модуля (например, MS-DOS или ОС/2), если соответствующая подсистема доступна на локальном компьютере.
Строка может указать полный путь и имя файла модуля для выполнения или указать частичное имя. В случае частичного имени функция использует текущий диск и текущий каталог для выполнения спецификации. Функция не будет использовать путь поиска. Этот параметр должен включать расширение имени файла; расширение по умолчанию не предполагается.
Параметр
- c:\program.exe
- c:\program files\sub.exe
- c:\program files\sub dir\program.exe
- c:\program files\sub dir\program name.exe
Если исполняемый модуль является 16-разрядным приложением, lpApplicationName должно быть NULL, а строка, на которую указывает lpCommandLine, должен указывать исполняемый модуль, а также его аргументы.
Чтобы запустить пакетный файл, необходимо запустить интерпретатор команд; задайте lpApplicationName значение cmd.exe и задайте lpCommandLine следующим аргументам: /c плюс имя пакетного файла.
[in, out, optional] lpCommandLine
Командная строка, выполняемая.
Максимальная длина этой строки составляет 32 767 символов, включая символ Юникода, завершающий значение NULL. Если lpApplicationNameNULL, часть имени модуля lpCommandLine ограничена MAX_PATH символами.
Версия этой функции Юникода CreateProcessWможет изменить содержимое этой строки. Таким образом, этот параметр не может быть указателем на память только для чтения (например, const переменную или литеральную строку). Если этот параметр является постоянной строкой, функция может вызвать нарушение доступа.
Параметр lpCommandLine может иметь значение NULL. В этом случае функция использует строку, указанную lpApplicationName в качестве командной строки.
Если оба lpApplicationName и lpCommandLine неNULL, строка, указываемая на значение NULL, указываемая lpApplicationName указывает модуль для выполнения, а строка, указываемая на значение NULL, на которую указывает lpCommandLine указывает командную строку. Новый процесс может использовать GetCommandLine для получения всей командной строки. Процессы консоли, написанные в C, могут использовать argc и аргументы argv для анализа командной строки. Так как argv[0] — это имя модуля, программисты C обычно повторяют имя модуля в качестве первого маркера в командной строке.
Если lpApplicationName имеет значение NULL, первый маркер пробела с разделителями командной строки указывает имя модуля. Если вы используете длинное имя файла, содержащее пробел, используйте строки с кавычками, чтобы указать, где заканчивается имя файла, и аргументы начинаются (см. описание параметра lpApplicationName). Если имя файла не содержит расширения, .exe добавляется. Таким образом, если расширение имени файла .com, этот параметр должен включать расширение .com. Если имя файла заканчивается точкой (.) без расширения или если имя файла содержит путь, .exe не добавляется. Если имя файла не содержит путь к каталогу, система ищет исполняемый файл в следующей последовательности:
- Каталог, из которого загружено приложение.
- Текущий каталог родительского процесса.
- 32-разрядный системный каталог Windows. Используйте функцию GetSystemDirectory
, чтобы получить путь к этому каталогу. - 16-разрядный системный каталог Windows. Нет функции, которая получает путь к этому каталогу, но выполняется поиск. Имя этого каталога — System.
- Каталог Windows. Используйте функцию getWindowsDirectory
GetWindowsDirectory, чтобы получить путь к этому каталогу. - Каталоги, перечисленные в переменной среды PATH. Обратите внимание, что эта функция не выполняет поиск пути для каждого приложения, указанного разделом реестра пути приложений. Чтобы включить этот путь для каждого приложения в последовательность поиска, используйте функцию
ShellExecute.
[in, optional] lpProcessAttributes
Указатель на структуру SECURITY_ATTRIBUTES, которая определяет, может ли возвращенный дескриптор нового объекта процесса наследоваться дочерними процессами. Если lpProcessAttributes null, то дескриптор не может быть унаследован.
Элемент lpSecurityDescriptor структуры указывает дескриптор безопасности для нового процесса. Если lpProcessAttributes имеет значение NULL или lpSecurityDescriptor NULL, процесс получает дескриптор безопасности по умолчанию. Списки управления доступом в дескрипторе безопасности по умолчанию для процесса получены из основного маркера создателя.Windows XP: списки управления доступом в дескрипторе безопасности по умолчанию для процесса, исходя из основного или олицетворения создателя. Это поведение изменилось с Windows XP с пакетом обновления 2 (SP2) и Windows Server 2003.
[in, optional] lpThreadAttributes
Указатель на структуру SECURITY_ATTRIBUTES, которая определяет, может ли возвращаемый дескриптор к новому объекту потока наследоваться дочерними процессами. Если lpThreadAttributes имеет значение NULL, дескриптор не может быть унаследован.
Элемент lpSecurityDescriptor структуры задает дескриптор безопасности для основного потока. Если lpThreadAttributes имеет значение NULL или lpSecurityDescriptor имеет значение NULL, поток получает дескриптор безопасности по умолчанию. Списки управления доступом в дескрипторе безопасности по умолчанию для потока приходят из маркера процесса.Windows XP: списки управления доступом в дескрипторе безопасности по умолчанию для потока, исходя из основного или олицетворения создателя. Это поведение изменилось с Windows XP с пакетом обновления 2 (SP2) и Windows Server 2003.
[in] bInheritHandles
Если этот параметр имеет значение TRUE, каждый наследуемый дескриптор в вызывающем процессе наследуется новым процессом. Если параметр имеет значение FALSE, дескриптор не наследуется. Обратите внимание, что унаследованные дескрипторы имеют одинаковые значения и права доступа, что и исходные дескрипторы. Дополнительные сведения о наследуемых дескрипторах см. в разделе "Примечания".
службах терминалов: нельзя наследовать дескрипторы между сеансами. Кроме того, если этот параметр имеет значение TRUE, необходимо создать процесс в том же сеансе, что и вызывающий объект.
процессы защищенного процесса (PPL): наследование универсального дескриптора блокируется, когда процесс PPL создает процесс, отличный от PPL, так как PROCESS_DUP_HANDLE не допускается из процесса, отличного от PPL, в процесс PPL. См.
[in] dwCreationFlags
Флаги, управляющие классом приоритета и созданием процесса. Список значений см. в разделе Флаги создания процессов.
Этот параметр также управляет классом приоритета нового процесса, который используется для определения приоритетов планирования потоков процесса. Список значений см. в разделе GetPriorityClass. Если ни один из флагов класса приоритета не указан, класс приоритета по умолчанию используется для NORMAL_PRIORITY_CLASS, если только класс приоритета процесса создания не IDLE_PRIORITY_CLASS или BELOW_NORMAL_PRIORITY_CLASS. В этом случае дочерний процесс получает класс приоритета по умолчанию вызывающего процесса.
Если параметр dwCreationFlags имеет значение 0:
- Процесс наследует как режим ошибки вызывающего объекта, так и консоли родительского элемента.
- Предполагается, что блок среды для нового процесса содержит символы ANSI (дополнительные сведения см. в разделе lpEnvironment параметре).
- 16-разрядное приложение под управлением Windows выполняется на общей виртуальной машине DOS (VDM).
[in, optional] lpEnvironment
Указатель на блок среды для нового процесса. Если этот параметр null, новый процесс использует среду вызывающего процесса.
Блок среды состоит из блока, завершаемого значением NULL, для строк, завершаемых значением NULL. Каждая строка находится в следующей форме:
имя=значение\0
Так как знак равенства используется в качестве разделителя, он не должен использоваться в имени переменной среды.
Блок среды может содержать символы Юникода или ANSI. Если блок среды, на который указывает lpEnvironment содержит символы Юникода, убедитесь, что dwCreationFlags включает CREATE_UNICODE_ENVIRONMENT.
Версия ANSI этой функции CreateProcessA завершается ошибкой, если общий размер блока среды для процесса превышает 32 767 символов.
Обратите внимание, что блок среды ANSI завершается двумя нулевыми байтами: один для последней строки, еще один для завершения блока. Блок среды Юникода завершается четырьмя нулевыми байтами: два для последней строки, еще два для завершения блока.
[in, optional] lpCurrentDirectory
Полный путь к текущему каталогу для процесса. Строка также может указать UNC-путь.
Если этот параметр null, новый процесс будет иметь тот же текущий диск и каталог, что и вызывающий процесс. (Эта функция предоставляется в основном для оболочк, которые должны запустить приложение и указать его начальный диск и рабочий каталог.)
[in] lpStartupInfo
Указатель на структуру STARTUPINFO или STARTUPINFOEX.
Чтобы задать расширенные атрибуты, используйте структуру STARTUPINFOEX и укажите EXTENDED_STARTUPINFO_PRESENT в параметре dwCreationFlags.
Обработка в STARTUPINFO или STARTUPINFOEX должна быть закрыта с CloseHandle, если они больше не нужны.
[out] lpProcessInformation
Указатель на структуру PROCESS_INFORMATION, которая получает идентификационные сведения о новом процессе.
Маркеры в PROCESS_INFORMATION должны быть закрыты с помощью CloseHandle, если они больше не нужны.
Возвращаемое значение
Если функция выполнена успешно, возвращаемое значение ненулевое.
Если функция завершается ошибкой, возвращаемое значение равно нулю. Чтобы получить расширенные сведения об ошибке, вызовите 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 не отключен и может использоваться для прерывания группы процессов или процессов.
По умолчанию передача TRUE в качестве значения параметра bInheritHandles приводит ко всем наследуемым дескрипторам нового процесса. Это может быть проблематично для приложений, которые создают процессы из нескольких потоков одновременно, но хотят, чтобы каждый процесс наследовал разные дескрипторы. Приложения могут использовать функцию updateProcThreadAttributeList с параметром PROC_THREAD_ATTRIBUTE_HANDLE_LIST для предоставления списка дескрипторов, наследуемых определенным процессом.
Замечания по безопасности
Первый параметр, lpApplicationName, может быть NULL, в этом случае имя исполняемого файла должно находиться в строке с разделителями пробелов, на которую указывает lpCommandLine. Если в имени исполняемого файла или пути есть пробел, существует риск того, что другой исполняемый файл может выполняться из-за того, как функция анализирует пробелы. Следующий пример является опасным, так как функция попытается запустить "Program.exe", если она существует, а не "MyApp.exe". LPTSTR szCmdline = _tcsdup(TEXT("C:\\Program Files\\MyApp -L -S"));
CreateProcess(NULL, szCmdline, /* ... */);
Если злоумышленник должен был создать приложение с именем "Program.exe" в системе, любая программа, которая неправильно вызывает CreateProcess с помощью каталога Program Files будет запускать это приложение вместо предполагаемого приложения.
Чтобы избежать этой проблемы, не передайте NULL для lpApplicationName. Если вы передаете NULL для lpApplicationName, используйте кавычки вокруг пути исполняемого файла в 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] |
целевая платформа | Виндоус |
заголовка | processthreadsapi.h (включая Windows.h в Windows Server 2003, Windows Vista, Windows 7, Windows Server 2008 Windows Server 2008 R2) |
библиотеки |
Kernel32.lib |
DLL | Kernel32.dll |