Использование консоли в приложении с графическим интерфейсом в Windows, только если она запускается из консоли

Мое приложение представляет собой приложение с графическим интерфейсом, которое имеет полезную (хотя и необязательную) информацию через терминал (через cout).

В Windows у меня либо появляется консоль (путем компиляции как консольного приложения, либо ее динамического размещения), либо у меня нет.

Я намерен использовать консоль, если она запускается из консоли, но полностью игнорировать консоль, если это не так. (По сути, что происходит в Linux и OS X).

Я не хочу перенаправлять в файл (и в случае использования cin, это не жизнеспособное решение в любом случае).

Есть ли способ присоединить приложение с графическим интерфейсом в Windows к консоли, из которой оно запускается, если и только если оно запускается из консоли?

4

Решение

и в случае использования cin, это не жизнеспособное решение в любом случае

Это убийственная деталь в вашем вопросе. Это просто на бумаге, просто сначала вызовите AttachConsole (ATTACH_PARENT_PROCESS), чтобы попытаться подключиться к существующей консоли. Это не удастся, когда ваша программа будет запущена из программы с графическим интерфейсом, такой как Explorer или ярлык на рабочем столе. Так что, если он возвращает FALSE, тогда вызовите AllocConsole (), чтобы создать собственную консоль.

С помощью CIN проблема, однако. Командный процессор обращает внимание на ваш EXE и проверяет, является ли это приложением в режиме консоли или приложением с графическим интерфейсом. Он обнаружит приложение GUI в вашем случае, а затем не дождитесь завершения процесса. Он снова отображает подсказку и ждет ввода. Затем вы также будете ждать ввода, но потеряете, командный процессор попал туда первым. Ваш вывод также смешивается с командной строкой, легко решить проблему.

Для этого есть простой обходной путь, ваш пользователь должен запустить вашу программу с start /wait yourapp сказать командному процессору дождаться завершения процесса. Проблема в том, что никто никогда не использует это. И пользователь не поймет, что происходит, когда он вводит ввод, намереваясь ввести его в вашу программу, но на самом деле он интерпретируется командным процессором. Создание таинственного сообщения об ошибке или форматирование жесткого диска.

Только два хороших способа решить эту неразрешимую проблему. Либо создайте свою программу как приложение в режиме консоли, либо вызовите FreeConsole (), когда вы обнаружите, что хотите отобразить графический интерфейс. Или всегда вызывайте AllocConsole (). Это не отличные альтернативы. Первый подход — тот, который используется Java JVM в Windows. Одна из самых старых ошибок, поданных против JVM и заставляющая программистов на Java полностью вырваться из вспыхивающего окна консоли.

Третий вариант — единственный достойный, и тот, который вам не нужен, создайте другой EXE-файл, который всегда будет использовать консоль. Как и Java, javaw.exe против java.exe.

Трюк возможен, вы можете переименовать этот файл из «yourapp2.exe» в «yourapp.com». Сначала он будет выбран, когда пользователь введет «yourapp» в командной строке, ярлык на рабочем столе все еще может указывать на «yourapp.exe». Visual Studio использует этот трюк, devenv.com против devenv.exe.

12

Другие решения

Ты можешь проверить CONSOLE_SCREEN_BUFFER_INFO (с помощью GetConsoleScreenBufferInfo) при запуске, чтобы определить, запускались ли вы из существующей консоли. Если позиция буфера равна 0,0, вы запускались снаружи консоли. Подробности смотрите в этом Статья базы знаний Майкрософт который описывает процесс.

Чтобы это работало, вам нужно скомпилировать ваше приложение как консольное приложение (используя /SUBSYSTEM:CONSOLE), а затем отсоедините себя от консоли, если приложение запустило новую консоль (буфер в 0,0). Это заставит программу правильно «присоединиться» к вызывающей консоли при запуске из командной строки.

1

Как уже отмечали другие, вы должны создать консольное приложение и оконное приложение. Итак, вы бы в конечном итоге console.exe а также app.exe, Чтобы сделать это менее очевидным в командной строке, вы можете воспользоваться трюком PATHEXT, например: Devenv делает. cmd.exe обрабатывает файл как команду, если его расширение находится в переменной среды PATHEXT. COM есть по умолчанию, поэтому вы можете переименовать console.exe в app.com, разрешив команду app запустить консольное приложение, подключенное к текущей консоли.

Примечание. Конечно, консольное приложение может отображать графический интерфейс при желании.

Разница в сборке между app.com и app.exe зависит от вашей системы сборки, но это может быть только один атрибут, который устанавливает тип вывода. С msbuild (для файлов .vcxproj) это просто вопрос другой конфигурации сборки.

0

вы можете создать приложение в консоли, которое получает строку с помощью argc и печатает ее;

////
int main(int argc, char *argv[])
{
//here print argv....using cout or printf
}

сохраните файл как console.exe в папке вашего приложения.
Теперь в вашем приложении, если вы хотите увидеть любую строку в консоли, вы можете вызвать команду

system("console.exe this is the line i want to print and see in console");
0
По вопросам рекламы ammmcru@yandex.ru