CreateProcess

 

Функция CreateProcess создаёт новый процесс и его главный поток. Новый процесс выполняет указанный исполняемый файл.

 

BOOL CreateProcess(

 

    LPCTSTR lpApplicationName,  // указатель на имя исполняемого файла

    LPTSTR lpCommandLine,       // указатель на командную строку

    LPSECURITY_ATTRIBUTES lpProcessAttributes, // указатель на атрибуты безопасности процесса

    LPSECURITY_ATTRIBUTES lpThreadAttributes,            // указатель на атрибуты безопасности потока

    BOOL bInheritHandles,           // указатель на флаг наследования

    DWORD dwCreationFlags,      // флаги создания

    LPVOID lpEnvironment,          // указатель на новый блок среды

    LPCTSTR lpCurrentDirectory,  // указатель на имя текущего каталога

    LPSTARTUPINFO lpStartupInfo,          // указатель на структуру STARTUPINFO

    LPPROCESS_INFORMATION lpProcessInformation // указатель на структуру PROCESS_INFORMATION 

   );     

 

Параметры

 

lpApplicationName

 

Указатель на строку с нольтерминатором, содержащую модуль для выполнения.

 

Строка может задавать полный путь и имя файла исполняемого модуля.

Строка может задавать частичное имя. В этом случае, функция использует текущее устройство и текущий каталог для дополнения спецификации.

Параметр lpApplicationName может быть и NULL. В этом случае имя модуля берётся из командной строки lpCommandLine.

Указанный модуль может быть приложением Win32. Либо он может быть модулем другого типа (например MS-DOS или OS/2), если ассоциированная система присутствует на локальном компьютере.

 

В Windows NT: Если исполняемый модуль является 16-битным приложением, lpApplicationName параметр должен быть NULL, и строка указываемая параметром lpCommandLine должна задавать этот исполняемый модуль. 16-битное приложение единственное, которое выполняется как VDM или WOW процесс.

 

lpCommandLine

 

Указатель на строку с нольтерминатором, которая задаёт командную строку выполнения.

Параметр lpCommandLine может быть NULL. В этом случае, функция использует строку, на которую указывает параметр lpApplicationName.

Если оба параметра lpApplicationName и lpCommandLine ненулевые, *lpApplicationName указывает исполняемый модуль, и *lpCommandLine указывает командную строку. Новый процесс может использовать функцию GetCommandLine для получения командной строки. Си-процесс времени выполнения может использовать аргументы argc и argv.

 

Если параметр lpApplicationName нулевой, то первый параметр командной строки указывает имя модуля. Если имя модуля не содержит расширения, подразумевается .EXE. если имя файла оканчивается точкой без расширения или имя файла содержит путь, .EXE не добавляется. Если имя файла не содержит путь, то Windows ищет исполняемый файл в следующем порядке:

  1. Каталог из которого было загружено приложение.
  2. Текущий каталог родительского процесса.
  3. В Windows 95: Системный каталог Windows. Используйте функцию GetSystemDirectory для определения этого пути.
    В Windows NT: 32-битный системный каталог Windows. Используйте функцию GetSystemDirectory для определения этого пути. Имя этого каталога SYSTEM32.
  4. В Windows NT: 16-битный системный каталог Windows. Нет специальной функции Win32, возвращающей этот каталог, но она может быть найдена. Имя этого каталога SYSTEM.
  5. Каталог Windows. Используйте функцию GetWindowsDirectory для определения этого пути.
  6. Каталоги описанные в переменной среды PATH.

 

Если процесс основан на платформе MS-DOS или Windows, то параметр lpCommandLine должен содержать полную командную строку, первый элемент которой является именем приложения. Так как это также работает и для Win32-платформенных приложений, этот случай является универсальным.

 

lpProcessAttributes

 

Указатель на структуру SECURITY_ATTRIBUTES, которая определяет, будет ли возвращённый дескриптор на процесс наследуемым для дочерних процессов. Если этот параметр нулевой, то декскриптор не может быть наследуемым.

 

В Windows NT: поле структуры lpSecurityDescriptor указывает на дескриптор безопасности нового процесса. Если lpProcessAttributes нулевой, процесс получает дескриптор безопасности по-умолчанию.

 

В Windows 95: поле структуры lpSecurityDescriptor игнорируется.

 

lpThreadAttributes

 

Указатель на структуру SECURITY_ATTRIBUTES, которая определяет, будет ли возвращённый дескриптор на процесс наследуемым для дочерних процессов. Если этот параметр нулевой, то декскриптор не может быть наследуемым.

 

В Windows NT: поле структуры lpSecurityDescriptor указывает на дескриптор безопасности главного потока. Если lpThreadAttributes нулевой, поток получает дескриптор безопасности по-умолчанию.

 

В Windows 95: поле структуры lpSecurityDescriptor игнорируется.

 

bInheritHandles

 

Указывает на то, будет ли процесс наследовать дескрипторы вызывающего его процесса. Если этот параметр TRUE, то каждый открытый дескриптор вызывающего процесса будет наследоваться новым процессом. Наследуемые дескрипторы имеют те же самые значения и права доступа, что и оригинальные.

 

dwCreationFlags

 

Указывает дополнительные флаги, контролирующие класс приоритета и создания процесса. Могут использоваться следующие флаги в любых комбинациях, кроме особо отмеченных:

 

Значение

Описание

CREATE_DEFAULT_ERROR_MODE

Новый процесс не наследует режим ошибки вызывающего процесса. С другой стороны, CreateProcess даёт текущий режим ошибки по умолчанию. Приложение устанавливает текущий режим ошибки по умолчанию вызовом SetErrorMode.

Этот флаг обычно используется для многопотоковых приложений – оболочек, которые запускаются с отключением «трудных» (hard) ошибок.

Решением по умолчанию для CreateProcess является наследование новым процессом режима ошибки вызывающего процесса. Установка этого флага меняет это решение, принимаемое по умолчанию.

CREATE_NEW_CONSOLE

Новый процесс имеет новую консоль, в противоположность наследуемой родительской консоли.

Этот флаг не может устанавливаться совместно с флагом DETACHED_PROCESS.

CREATE_NEW_PROCESS_GROUP

Новый процесс является корневым для новой группы процессов. Группа процессов содержит все процессы, являющиеся наследниками этого корневого процесса. Идентификатор новой группы процессов совпадает с идентификатором, который возвращается параметром lpProcessInformation. Группы процессов используются функцией GenerateConsoleCtrlEvent для разрешения передачи сигналов CTRL+C или CTRL+BREAK группе консольных процессов.

CREATE_SEPARATE_WOW_VDM

Только для Windows NT: Этот флаг устанавливается только при старте 16-битных Windows приложений. Если установлен, новый процесс запускается на приватной Виртуальной DOS Машине (VDM). По умолчанию, все 16-битные Windows приложения запускаются как потоки в единственной, совместно используемой VDM. Причиной является то, что при сбое разрушается одна Виртуальная DOS Машина; любые другие программы, запущенные в других VDM продолжают функционировать нормально. Также, 16-битные Windows приложения, запущенные в разных VDM имеют и раздельные запросы на ввод. Это значит, что если одно приложение даёт сбой, приложения в других отдельных VDM продолжают получать ввод.

CREATE_SHARED_WOW_VDM

Только для Windows NT: Этот флаг устанавливается только при старте 16-битных Windows приложений. Если переключатель DefaultSeparateVDM в секции Windows файла WIN.INI равен TRUE, этот флаг вынуждает функцию CreateProcess перекрывать этот переключатель и запускать новый процесс в совместной Виртуальной DOS Машине.

CREATE_SUSPENDED

Основной поток нового процесса создаётся в спящем режиме, и не запускается до тех пор, пока не вызвана функция ResumeTread.

CREATE_UNICODE_ENVIRONMENT

Если установлен, то блок среды указанный параметром lpEnvironment использует символы Unicode. Если опущен, то блок среды использует символы ANSI.

DEBUG_PROCESS

Если установлен, вызывающий процесс становится отладчиком, а новый поток становится отлаживаемым. Система оповещает отладчик обо всех отладочных событиях происходящих в новом процессе.

Если вы создаёте процесс с этим флагом, только вызывающий поток (поток, который вызвал CreateProcess) может обращаться к функции WaitForDebugEvent.

DEBUG_ONLY_THIS_PROCESS

Если не установлен и вызывающий процесс является отлаживаемым, новый процесс будет ещё одним отлаживаемым процессом отладчиком которого будет являться отладчик вызывающего процесса. Если вызывающий процесс не является отлаживаемым, то никаких акций, связанных с отладкой не применяется.

DETACHED_PROCESS

Для консольных процессов, новый процесс не имеет доступа к консоли родительского процесса. Этот флаг не может использоваться совместно с флагом CREATE_NEW_CONSOLE.

 

Параметр dwCreationFlags также контролирует класс приоритета процесса, который используется при определении управления приоритетами потоков процесса. Если ни один из следующих флагов приоритетов не установлен, по умолчанию классом приоритета является NORMAL_PRIORITY_CLASS, а классом приоритета создания процесса является IDLE_PRIORITY_CLASS. В этом случае, классом приоритета по умолчанию для дочернего процесса является IDLE_PRIORITY_CLASS. Может указываться один из следующих флагов:

 

Приоритет

Описание

HIGH_PRIORITY_CLASS

Указывает, что процесс выполняет критичные ко времени задачи, которые должны выполняться незамедлительно. Потоки с высоким классом приоритета превалируют над потоками с классами приоритета IDLE и NORMAL. Примером является Диспетчер задач Windows, который должен быстро реагировать на вызов пользователя, невзирая на загрузку операционной системы. Будьте осторожны при использовании этого класса приоритета, так как такие приложения могут использовать все доступные ближайшие циклы процессора.

IDLE_PRIORITY_CLASS

Указывает, что потоки процесса работают только тогда, когда система не занята и прерываются потоками с более высоким классом приоритета. Примером такого процесса является хранитель экрана. Такой класс приоритета наследуется дочерними процессами.

NORMAL_PRIORITY_CLASS

Указывает на нормальный процесс без специальных требований к управлению задачами.

REALTIME_PRIORITY_CLASS

Указывает, что процесс имеет максимально допустимый приоритет. Потоки с классом приоритета реального времени превалируют над потоками любых других классов приоритета, включая процессы операционной системы, выполняющие важные задачи. К примеру такой процесс может выполнятся быстрее самого короткого интервала очистки дискового кэша или он может приводить к зависанию мыши.

 

lpEnvironment

 

Указывает на блок среды. Если этот параметр нулевой, то новый процесс использует среду вызывающего процесса.

 

Блок среды состоит из блока строк с нольтерминаторами, оканчивающегося нулём. Каждая строка имеет вид:

 

имя=значение

 

Так как знак равенства используется как разделитель, он не должен присутствовать в имени переменной среды. Если приложение обеспечивает блок среды, кроме тех случаев, когда этот параметр NULL, информация о текущих каталогах системных устройств автоматически не указываются новому процессу. Более подробно эта ситуация описывается в разделе Замечание.

Блок среды может содержать символы Unicode или ANSI. Если блок среды указанный параметром lpEnvironment содержит символы Unicode, поле флага dwCreationFlags CREATE_UNICODE_ENVIRONMENT должно быть установлено. Если блок содержит символы ANSI, данное поле флага должно быть очищено.

 

Заметьте, что блок среды ANSI оканчивается двумя нулевыми байтами: один заканчивает последнюю строку, и ещё один означает конец блока. Блок среды Unicode оканчивается четырьмя нулевыми байтами: два для последней строки и ещё два окончания блока.

 

lpCurrentDirectory

 

Указывает на строку с нольтерминатором, которая содержит текущее устройство и каталог для дочернего процесса. Строка должна состоять из полного пути и имени файла с указанием буквы устройства. Если этот параметр NULL, новый процесс создаётся с такими же текущим устройством и каталогом, что и у вызывающего процесса. Эта опция предусмотрена для оболочек, которым необходимо запускать приложения и указывать их инициализированные устройства и рабочие каталоги.

 

lpStartupInfo

 

Указатель на структуру STARTUPINFO, которая указывает как должно появляться главное окно нового процесса.

 

lpProcessInformation

 

Указатель на структуру PROCESS_INFORMATION, в которую записывается идентификационная информация нового процесса.

 

Возвращаемое значение

 

Если функция успешна, возвращаемое значение ненулевое.

Если функция неудачна, возвращается ноль. Для получения подробной информации об ошибке вызывайте функцию GetLastError.

 

Замечание

 

Функция CreateProcess предназначена для запуска новой программы. Функции WinExec и LoadModule также работают, но не предоставляют таких возможностей, как  CreateProcess.

В дополнение к созданию процесса, CreateProcess также создаёт потоковый объект. Поток создаётся с инициализационным стеком, чей размер описан в заголовке образа исполняемого файла. Поток начинает выполнение в точке входа этого образа.

 

Дескрипторы нового процесса и нового потока создаются с полными правами доступа. Для обоих дескрипторов, если дескриптор безопасности не обеспечивается, то дескриптор может быть использован любой функцией, которая запрашивает дескриптор объекта этого типа. При обеспечении дескриптора безопасности, проверка доступа производится при любом запросе на использование дескриптора. Если проверка не гарантирует доступ, то запрашивающий процесс не может использовать дескриптор данного потока.

 

Процессу назначается 32-битный идентификатор процесса. Идентификатор действует до тех пор, пока процесс не завершится. Он может использоваться для распознавания процесса, или для указания функции OpenProcess для открытия дескриптора процесса. Инициализирующему потоку в процессе также назначается 32-битный идентификатор потока. Этот идентификатор доступен до тех пор, пока поток не завершится и может использоваться для уникального распознавания потока внутри системы. Эти идентификаторы возвращаются в структуре PROCESS_INFORMATION.

 

При указывании имени приложения в строках lpApplicationName или lpCommandLine, не имеет значения, содержит ли имя приложения расширение файла, с одним исключением: приложения для платформ MS-DOS или Windows, чьи файлы с расширением .COM должны содержать расширение .COM.

 

Вызывающий поток может использовать функцию WaitForInputIdle для ожидания окончания инициализации нового процесса и приостановить пользователем ввод данных без его правильной обработки. Это может использоваться при синхронизации родительского и дочернего процессов, так как CreateProcess возвращается без ожидания завершения инициализации нового процесса. Например, вызывающий процесс должен вызвать WaitForInputIdle до попыток отыскать окно ассоциированное с новым процессом.

 

Предпочитаемый путь для завершения процесса это использование функции ExitProcess, потому как эта функция предупреждает все динамически связанные библиотеки (DLL), используемые процессом о предстоящем его завершении. Другие инструменты завершения процесса не уведомляют присоединённые к нему библиотеки. Заметьте, что при вызове потоком ExitProcess, другие потоки процесса завершаются без возможности выполнять какой-либо дополнительный код (включая завершающий код потока присоединённых библиотек).

 

Функции ExitProcess, ExitThread, CreateThread, CreateRemoteThread, и процесс который запускается (как результат вызова CreateProcess) однозначимы относительно друг друга в одном процессе. Только одно из этих событий может происходить в адресном пространстве в одно и то же время. Это приводит к следующим ограничениям:

 

Созданный процесс присутствует в системе до тех пор, пока не осталось ни одного потока внутри процесса незавершёнными и все дескрипторы процесса или любого из его потока не закрыты вызовом CloseHandle. Если эти дескрипторы не нужны, лучше всего закрывать их сразу же после создания процесса.

Когда последний поток завершён, происходит следующее:

 

 

Если текущий каталог устройства C это \MSVC\MFC, есть переменная среды, названная =C:, чьё значение равно C:\MSVC\MFC. Как было сказано в предыдущем описании параметра lpEnvironment, такая текущая информация о каталогах автоматически не указывается новому процессу когда этот параметр ненулевой. Приложение должно само создавать =X строки переменных среды, сортировать их в алфавитном порядке (так как Windows NT и Windows 95 используют сортированную среду), и затем помещать их в блок среды, на который указывает lpEnvironment. Обычно такие строки идёт в самом начале блока среды для избежания путаницы при сортировке всех переменных среды.

 

Есть один путь для определения переменной текущего каталога для устройства X – это вызов функции GetFullPathName("X:",. .). Это позволяет отказаться от сканирования приложением блока среды. Если возвращаемый путь возвращается как X:\, нет необходимости создавать переменную среды, так как для нового процесса текущий каталог по умолчанию для устройства X это корневой каталог.

 

Дескриптор, возвращаемый функцией CreateProcess имеет доступ PROCESS_ALL_ACCESS для объекта процесса.

 

Текущий каталог указанный в параметре lpCurrentDirectory, является текущим каталогом для дочернего процесса.

Текущий каталог указанный во втором параметре командной строки lpCommandLine является текущим каталогом родительского процесса.

 

В Windows NT: Когда процесс создаётся с флагом CREATE_NEW_PROCESS_GROUP, происходит вызов функции SetConsoleCtrlHandler(NULL,TRUE); это означает, что у нового процесса отключается CTRL+C. Это хорошо для оболочек, которые сами обрабатывают CTRL+C, и выборочно пропускают этот сигнал своим попроцессам. CTRL+BREAK не отключается и может использоваться для прерывания процесса или группы процессов.

 

См. также

 

AllocConsole, CloseHandle, CreateRemoteThread, CreateThread, ExitProcess, ExitThread, GenerateConsoleCtrlEvent, GetCommandLine, GetEnvironmentStrings, GetExitCodeProcess, GetFullPathName, GetStartupInfo, GetSystemDirectory, GetWindowsDirectory, LoadModule, OpenProcess, PROCESS_INFORMATION, ResumeThread, SECURITY_ATTRIBUTES, SetConsoleCtrlHandler, SetErrorMode, STARTUPINFO, TerminateProcess, WaitForInputIdle, WaitForDebugEvent, WinExec

 

Hosted by uCoz