【发布时间】:2021-12-30 15:57:27
【问题描述】:
Windows 10,C++。我有一个图形应用程序,它打开一个控制台,写一些东西,然后等到用户点击控制台上的关闭。我只想让控制台关闭,但整个应用程序都会退出。是的,处理程序已输入。我还看到这是 10 多年前的一个问题。那么,有没有其他方法可以解决这个问题?
// Graphic app makes following calls
...
AllocConsole();
SetConsoleCtrlHandler(ConsoleCloseHandler, TRUE);
...
处理程序定义如下。
BOOL WINAPI ConsoleCloseHandler(DWORD signalType) {
switch (signalType) {
case CTRL_CLOSE_EVENT:
case CTRL_C_EVENT:
FreeConsole();
return TRUE;
default: return FALSE;
}
}
【问题讨论】:
-
确实如此。简而言之,只要单击 x 关闭控制台,Windows(子系统)就会开始清理并准备退出。几个世纪后,它调用处理程序只是为了查看您是否想做更多的清理工作。此时,唯一的行动就是结束该过程。因此,当文档说返回 true 时不会调用进一步的处理程序时,它会产生误导。似乎是在说,信号将被忽略。这不是真的。
-
我没有将此标记为重复,因为我对我提出的问答有一个答案,这将使我投票结束它可能存在利益冲突。但是,我要指出,我必须在生产应用程序中处理这个完全相同的问题。我的解决方法是在我的应用程序运行时禁用控制台标题栏中的关闭(“X”)按钮,以便用户无法单击它。但是,这必须非常小心地完成,以确保在应用程序崩溃时关闭按钮不会被禁用。我在 C++ 中使用 RAII 来确保这是不可能的。
-
谢谢。那对我不起作用。我希望用户真正关闭控制台。简而言之,可能会要求主应用程序(IDE)运行(发布版本)一些其他应用程序,这些应用程序可能是控制台或 GUI 应用程序。我解决这个问题的方法是感知它是什么类型的应用程序,并以某种方式使其调用 main() 或 WinMain()。在调用 CreateProcess() 之前。感觉解释起来很复杂,但我为此目的使用了这个论点(在我正在工作的上下文中)。该技术不能用于通用目的,所以我在这里不提。
-
在这种情况下,我同意 Remy Lebeau 的评论,即您应该使应用程序始终是 Windows 应用程序(具有 WinMain 入口点)。这不会自动显示任何用户界面,因此它适用于 UI 应用和“无头”应用。如果你想要一个控制台窗口,那么只需在 WinMain 中调用
AllocConsole。这样一来,您的应用就不会在控制台窗口关闭时被强制关闭,因为它是在自己的上下文中运行的。
标签: c++ windows winapi console