Ответ Jdigital указывает на Блог Раймонда Чена , в котором объясняется, почему у вас не может быть приложения, которое является одновременно консольной и не консольной *
программой: ОС Необходимо знать , прежде чем программа запустит , какую подсистему использовать. Когда программа запустится, будет слишком поздно вернуться и запросить другой режим.
Ответ Кейда указывает на статью о запуске приложения .Net WinForms с консолью . Он использует технику вызова AttachConsole
после запуска программы. Это позволяет программе писать обратно в консольное окно командной строки, которая запустила программу. Но комментарии в этой статье указывают на то, что я считаю фатальным недостатком: Дочерний процесс на самом деле не управляет консолью. Консоль продолжает принимать ввод от имени родительского процесса и родительского процесса не знает, что ему следует дождаться, пока ребенок закончит бег, прежде чем использовать консоль для других целей.
Статья Чена указывает на статью Цзюньфэна Чжана, в которой объясняется пара других техник .
Во-первых, devenv использует. Это работает на самом деле две программы. Одна из них - devenv.exe , которая является основной программой с графическим интерфейсом, а другая - devenv.com , которая обрабатывает задачи в консольном режиме, но если она используется не в консоли. таким же образом он перенаправляет свои задачи в devenv.exe и завершает работу. Этот метод основан на правиле Win32, согласно которому com файлы выбираются раньше, чем exe , когда вы вводите команду без расширения файла.
Существует более простой вариант, чем это делает Windows Script Host. Он предоставляет два совершенно разных двоичных файла: wscript.exe и cscript.exe . Аналогично, Java предоставляет java.exe для консольных программ и javaw.exe для неконсольных программ.
Вторая техника Junfeng - это то, что ildasm использует. Он цитирует процесс, который прошел автор ildasm при его запуске в обоих режимах. В конечном счете, вот что он делает:
- Программа помечена как двоичный файл в режиме консоли, поэтому она всегда запускается с консоли. Это позволяет перенаправлению ввода и вывода работать в обычном режиме.
- Если программа не имеет параметров командной строки в консольном режиме, она перезапускается сама.
Недостаточно просто вызвать FreeConsole
, чтобы первый экземпляр перестал быть консольной программой. Это связано с тем, что процесс, который запустил программу, cmd.exe , «знает», что он запустил программу в режиме консоли и ожидает остановки программы. Вызов FreeConsole
приведет к тому, что ildasm прекратит использование консоли, но родительский процесс не запустится с помощью консоли.
Итак, первый экземпляр перезапускается сам (с дополнительным параметром командной строки, я полагаю). Когда вы вызываете CreateProcess
, вам нужно попробовать два разных флага: DETACHED_PROCESS
и CREATE_NEW_CONSOLE
, каждый из которых гарантирует, что второй экземпляр не будет подключен к родительской консоли. После этого первый экземпляр может завершиться и позволить командной строке возобновить обработку команд.
Побочным эффектом этого метода является то, что при запуске программы из интерфейса графического интерфейса все равно будет консоль. Он на мгновение мигнет на экране, а затем исчезнет.
Часть в статье Junfeng об использовании editbin для изменения флага режима консоли программы, я думаю, представляет собой красную сельдь. Ваш компилятор или среда разработки должны предоставить параметр или опцию для управления типом двоичного файла, который он создает. После этого не нужно ничего менять.
Суть в том, что вы можете иметь либо два двоичных файла, либо у вас может быть кратковременное мерцание окна консоли . Как только вы решите, какое зло меньше, у вас есть выбор реализации.
*
Я говорю не консольный вместо GUI , потому что в противном случае это ложная дихотомия. Тот факт, что программа не имеет консоли, не означает, что она имеет графический интерфейс. Приложение службы является ярким примером. Также программа может иметь консоль и windows.