2013-02-19 4 views
1

Я пытаюсь запустить процесс с помощью CreateProcess (...) и запустить его самостоятельно в отдельном окне консоли.CreateProcess не создает дополнительные окна консоли под Windows 7?

Я могу добиться этого с помощью функции системы («...»), но я предпочитаю CreateProcess, так как он дает мне возможность указать среду и рабочий каталог, получить дескриптор процесса, а также трубопровод stdin/когда мне нужно.

Все, что я нахожу в Интернете, - это обратная проблема, которая есть люди, имеющие дополнительные окна консоли и желающие избавиться от них! Похоже, что было обычное поведение в более ранних версиях Windows для открытия и отображения нового окна консоли?

Прямо сейчас, я не могу получить дополнительное окно, даже если я бегу «cmd.exe/с ...»

Я попытался использовать флаг STARTF_USESHOWWINDOW не повезло.

У кого-нибудь была эта проблема?

PS .: Окна графического интерфейса пользователя показаны, например. notepad.exe появится нормально.

Это мой код (в сущности)

PROCESS_INFORMATION processInfo; 
STARTUPINFOA startupInfo; 
ZeroMemory(&startupInfo,sizeof(startupInfo)); 
startupInfo.dwFlags |= CREATE_NEW_CONSOLE; 
startupInfo.dwFlags |= DETACHED_PROCESS; 
ok&=CreateProcessA(NULL, 
    const_cast<char*>(comand.c_str()), // safe for CreateProcessA 
    NULL, NULL, TRUE, NULL, NULL, NULL, 
    &startupInfo, &processInfo); 

Я пытаюсь запустить C: /Windows/system32/cmd.exe/с помощью программа работает, и я могу прочитать вывод данных из труба. Еще нет окна.

ответ

10

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(), чтобы получить его, а затем явно настроить.

2

Провод CREATE_NEW_CONSOLE в dwCreationFlags при звонке CreateProcess. Я не тестировал, но я подозреваю, что это заставляет создавать консольное окно (возможно, даже для не консольных процессов?) Вместо этого вы можете использовать DETACHED_PROCESS, который просто отделяется от родительской консоли.

 Смежные вопросы

  • Нет связанных вопросов^_^