Как я могу заставить приложение MFC блокироваться из командной строки?

Я модифицировал пример MFC для OpenCascade, добавив некоторые функции (это был пример HLR). Приложение использует архитектуру документ/представление, при этом класс документа выполняет большую часть работы.

Некоторым из новых функций не требуется графический интерфейс, поэтому программа завершает работу до открытия графического интерфейса, что я и выполняю, вызывая exit(0) из специализации CDocument.

Моя проблема в том, что для нашего рабочего процесса приложение MFC будет вызываться из командной строки Windows. Как только он вызывается, он возвращает управление оболочке и продолжает весело работать в фоновом режиме, независимо от того, открывает ли он графический интерфейс или нет. Мне нужно, чтобы приложение блокировалось из командной строки, независимо от того, открыт графический интерфейс или нет.

Я читал о CWinApp и CMDIFrameWnd, но если вы можете сделать блокировку своего приложения из командной строки, я не могу понять, как это сделать.


person HeywoodFloyd    schedule 20.06.2013    source источник
comment
Я бы сделал это консольным приложением с настройкой компоновщика /SUBSYSTEM:CONSOLE.   -  person drescherjm    schedule 20.06.2013
comment
Я думаю, что это также неявно изменит точку входа на main(), поэтому вам понадобится /entry:WinMain или что-то подобное в настройках компоновщика.   -  person Ulrich Eckhardt    schedule 20.06.2013
comment
У меня есть несколько вариантов решения этой проблемы здесь: стандартный вывод"> stackoverflow.com/questions/13840942/   -  person drescherjm    schedule 20.06.2013
comment
Спасибо за рекомендации по компиляции/запуску консольного приложения. Мы просто будем вызывать приложение из пакетного файла, который блокируется до тех пор, пока приложение не завершит работу.   -  person HeywoodFloyd    schedule 20.06.2013


Ответы (3)


Если вы настроите свой исполняемый файл как консольное приложение с параметром компоновщика /SUBSYSTEM:CONSOLE, командная строка будет заблокирована до выхода приложения. Помните, что консольное приложение может иметь графический интерфейс Windows.

Установка параметра компоновщика /SUBSYSTEM:CONSOLE имеет одну проблему, если вы сделаете это в качестве параметра компоновщика, вам придется настроить точку входа так, чтобы она была main() вместо winmain. В следующем потоке есть несколько обходных путей для этого (спасибо, что Ульрих Экхардт упомянул точку входа): Стандартный вывод Visual Studio 2012 C++

Есть и второй минус этого подхода. Если программа не запускается из окна консоли, приложение создаст для вас окно консоли. Это может запутать пользователей.

person drescherjm    schedule 20.06.2013
comment
Спасибо за все рекомендации по компиляции/запуску консольного приложения. Я не беспокоюсь о том, что запутаю пользователя, но я беспокоюсь, что целая куча операторов отладки printf, выводящихся на консоль, замедлит работу приложения. Вы знаете, будет ли это проблемой? - person HeywoodFloyd; 20.06.2013
comment
Разве вы не можете отключить их в своей сборке релиза или перенаправить их в файл? - person drescherjm; 20.06.2013
comment
Это немного смешно, что у нас так много отладки printf, но у нас есть так много (некоторые из них предоставлены субподрядчиками), что мы просто используем пакетное решение. Чисто из соображений экономии. - person HeywoodFloyd; 20.06.2013
comment
Итак, в обычном пакетном файле, вызывающем приложение Windows, приложение будет ждать, пока оно не закроется? Или есть какой-то вариант заставить это работать. Также, пожалуйста, опубликуйте свое пакетное решение в качестве ответа. Я бы проголосовал за это. - person drescherjm; 20.06.2013
comment
Спасибо drescherjm. Я собирался опубликовать это как ответ, но подсказка stackoverflow об ответах на ваши собственные вопросы заставила меня немного стыдиться. - person HeywoodFloyd; 21.06.2013

Вы не можете. EXE-файлы помечаются как консольные или программы Windows, и если это программа Windows, управление передается диспетчеру Windows, и консоль продолжает работать.

Лучше всего создать небольшое консольное приложение, которое вызывает CreateProcess для запуска приложения Windows, а затем просто WaitForSingleObject в дескрипторе hProcess для его завершения.

Более подробная техническая информация о том, почему это невозможно, доступна в блоге The Old New Thing здесь:

http://blogs.msdn.com/b/oldnewthing/archive/2009/01/01/9259142.aspx

person snowdude    schedule 20.06.2013

Если вы хотите заблокировать приложение MFC (или оконное приложение, как правило) и вывести его на консоль (сначала вам потребуется AttachConsole() или AllocConsole()), выполните свою работу в InitInstance (или эквивалентном методе), подождите для завершения любых потоков в ExitInstance, а затем запустите свою программу из командной строки, используя start /WAIT ‹ваше приложение› ‹ваши параметры›. Вам не нужно писать специальное консольное приложение, которое ждет... start уже делает это.

person Keelan    schedule 30.09.2020