Ответ 1
Единственное отличие заключается в том, что консольное приложение всегда создает консоль, если она не запускается с одного (или консоль активно отключается при запуске). С другой стороны, приложение Windows не создает консоль. Он все равно может прикрепляться к существующей консоли или создавать новый с помощью AllocConsole
.
Это делает приложения Windows лучше подходящими для приложений GUI или фоновых приложений, потому что вы обычно не хотите, чтобы для них создано окно терминала.
В более техническом примечании единственная разница между консолью и исполняемым файлом Windows - один байт в PE-заголовке файла exe
. Переключение этого байта вручную (например, с использованием шестнадцатеричного редактора) преобразует тип приложения. Это хорошо опубликованный хак, который используется для создания консольных приложений в VB6 (где этот тип приложений явно не поддерживается).
Чтобы определить и изменить тип подсистемы приложения, вам необходимо прочитать части заголовка PE. Адрес данных подсистемы не исправлен, поскольку он является частью дополнительного заголовка файла, позиция которого определяется адресом, хранящимся в заголовке файла DOS (в элементе e_lfanew
). Этот адрес фактически указывает на запись _IMAGE_NT_HEADERS
, которая, в свою очередь, включает структуру IMAGE_OPTIONAL_HEADER32
. У этого есть член int16
1) называемый Subsystem
. Значение члена равно 2 для приложения Windows и 3 для консольного приложения. Существуют и другие подсистемы (в частности, POSIX и ядро).
Я написал небольшое приложение VB6 для изменения подсистемы приложения, которое можно загрузить из ActiveVB в качестве исходного кода.
Формат PE не очень хорошо документирован, но этот документ может служить введением: Peering Inside PE: обзор формата исполняемого файла Win32 Portable.
1) Это не противоречит моему утверждению, что только один байт отличается: самый старший байт этого элемента всегда равен 0. Изменяется только младший значащий байт.