MSDN - действительно ваш лучший друг при работе с API Win32. Теперь соответствующие флагов создания для вас являются следующими:
(no flags set)
- дочерний процесс (тот, который начинается с CreateProcess()
) будет совместно использовать консоль с родительским процессом (процесс, который называется CreateProcess()
).
CREATE_NEW_CONSOLE
- дочерний процесс получит новую консоль, открытую в новом окне. Как явно говорит MSDN, этот флаг НЕ ДОЛЖЕН использоваться вместе сDETACHED_PROCESS
! И это именно тот флаг, который вы хотите использовать.
CREATE_NO_WINDOW
- дочерний процесс получит новую консоль, , но без какого-либо окна для нее. Это довольно удивительный флаг, поэтому я снова его повторю: дочерний процесс будет иметь консоль, на которую вы можете написать свой вывод, с которого вы можете попробовать прочитать ввод и т. Д .; эта консоль отличается от консоли родительского процесса; эта консоль невидима, у нее нет видимого окна, но она существует. Это полезно, скажем, для беспроблемного выполнения дочерних процессов в фоновом режиме. Обратите внимание, что этот флаг не действует при использовании с CREATE_NEW_CONSOLE
или DETACHED_PROCESS
- эти флаги переопределяют этот флаг. Также имейте в виду, что этот флаг игнорируется при запуске приложения GUI: он не получит невидимую консоль.
DETACHED_PROCESS
- дочерний процесс не получит никакой консоли. Вы не должны использовать этот флаг вместе сCREATE_NEW_CONSOLE
.
И теперь немного больше о правильном вызове CreateProcess()
. Прежде всего, вы должны использовать CreateProcessW()
. Я особенно устал от приложений, которые не могут получить доступ к файлам в каталоге с именем 日本語αβηλ
.
Во-вторых, даже если вы используете версию ANSI, укажите CREATE_UNICODE_ENVIRONMENT
флаг, если вы пройдете NULL
для окружающей среды. Если вы этого не сделаете, PATH
может закончиться сломанным в дочернем процессе, и эта ошибка крайне раздражает, чтобы проследить.
В-третьих, не следует const_cast<char*>command.c_str()
. Просто позвоните strdup()/wcsdup()
, а затем free()
после того, как звонок CreateProcess()
вернулся. Или, если вы действительно настаиваете на изменении command
на месте, пройдите &command[0]
в качестве параметра.
В-четвертых, не забудьте установить размер вашей STARTUPINFO
структуры: startupInfo.cb = sizeof(startupInfo)
. Современные Windows (по крайней мере, XP и 7) позволяют вам оставить это поле равным нулю без каких-либо вредных последствий, но это немного небрежное программирование, чтобы полагаться на это.
О, и пока мы здесь, вы упомянули, что используете CreateProcess()
, потому что, помимо всего прочего, он позволяет явно указать среду для ребенка. Ну, есть небольшая гаша о параметре lpEnvironment
, который документирован, но довольно легко упускается из виду. Когда вы укажете NULL
, ребенок наследует среду родителя. Когда вы указываете что-то не NULL
, окружение родителя НЕ ДОБАВЛЯЕТСЯ к нему. Если вы хотите добавить в среду родителя, вам нужно будет использовать GetEnvironmentStrings()
, чтобы получить его, а затем явно настроить.