Раймонд Чен недавно опубликовал (через месяц после того, как вопрос был размещен здесь на SO) короткую статью об этом:
Как написать программу, которая может быть запущена как консоль или приложение с графическим интерфейсом?
Вы не можете, но вы можете попытаться подделать это.
Каждое приложение PE содержит поле
в своем заголовке, который указывает, какой
подсистема, она была разработана для запуска
под. Ты можешь сказать
IMAGE_SUBSYSTEM_WINDOWS_GUI
отметить
себя как приложение Windows GUI,
или вы можете сказать
IMAGE_SUBSYSTEM_WINDOWS_CUI
сказать
что вы консольное приложение. Если
вы приложение GUI, то
Программа будет работать без консоли.
Подсистема определяет, как
ядро готовит исполнение
среда для программы. Если
Программа помечена как запущенная в
консольная подсистема, потом ядро
подключит консоль программы к
консоль своего родителя, создавая
новая консоль, если у родителя нет
консоль. (Это неполное
описание, но детали не
отношение к обсуждению.) На
С другой стороны, если программа помечена
работает как приложение с графическим интерфейсом, то
ядро запустит программу
без какой-либо консоли вообще.
В этой статье он указывает на другую статью Junfeng Zhang, в которой обсуждается, как несколько программ (Visual Studio и ildasm) реализуют это поведение:
Как сделать приложение как графическим, так и консольным приложением?
В случае VisualStudio существует два двоичных файла: devenv.com и devenv.exe. Devenv.com - это консольное приложение. Devenv.exe это приложение с графическим интерфейсом. При вводе devenv из-за правила проверки Win32 выполняется devenv.com. Если нет ввода, devenv.com запускает devenv.exe и завершает свою работу. Если есть входы, devenv.com обрабатывает их как обычное консольное приложение.
В случае ildasm есть только один двоичный файл: ildasm.exe. Сначала он компилируется как приложение с графическим интерфейсом. Позже editbin.exe используется, чтобы отметить его как консольную подсистему. В своем основном методе он определяет, должен ли он работать в режиме консоли или в режиме графического интерфейса. Если необходимо запустить режим графического интерфейса, он перезапускается как приложение с графическим интерфейсом.
В комментариях к статье Раймонда Чена, laonianren имеет это, чтобы добавить к краткому описанию Junfeng Zhang того, как работает Visual Studio:
devenv.com - это универсальное приложение-заглушка в консольном режиме. Когда он запускается, он создает три канала для перенаправления консоли stdin, stdout и stderr. Затем он находит свое собственное имя (обычно devenv.com), заменяет «.com» на «.exe» и запускает новое приложение (т.е. devenv.exe), используя конец чтения канала stdin и конец записи stdout. и трубы stderr как стандартные ручки. Затем он просто сидит и ждет выхода devenv.exe и копирует данные между консолью и каналами.
Таким образом, даже несмотря на то, что devenv.exe является приложением с графическим интерфейсом, он может читать и писать «родительскую» консоль, используя стандартные дескрипторы.
И вы можете использовать devenv.com для myapp.exe, переименовав его в myapp.com. Но вы не можете на практике, потому что это принадлежит MS.