嗯,是的,这是使用Windows控制台子系统的警告之一。当用户关闭控制台窗口时(无论控制台如何分配), 所有附加到控制台的进程都将终止 。对于控制台应用程序(即,专门针对控制台子系统的应用程序,而不是标准Windows应用程序),这种行为是很有意义的,但是在像您这样的情况下,这可能是一个很大的麻烦。
我知道的唯一解决方法是使用SetConsoleCtrlHandler
function,它允许您为Ctrl
+ C
和Ctrl
+Break
信号以及系统事件(例如用户关闭控制台窗口,用户注销或系统关闭)注册处理函数。。该文档说,如果您只想忽略这些事件,则可以传递null
第一个参数。例如:
[DllImport("kernel32")]
static extern bool SetConsoleCtrlHandler(HandlerRoutine HandlerRoutine, bool Add);
delegate bool HandlerRoutine(uint dwControlType);
static void Main()
{
AllocConsole();
SetConsoleCtrlHandler(null, true);
while (true) continue;
}
完美适用于Ctrl
+ C
和Ctrl
+Break
信号(否则也会导致您的应用程序终止),但不适用于您要查询的信号CTRL_CLOSE_EVENT
,即系统在用户关闭界面时生成的信号。控制台窗口。
老实说,我不知道如何防止这种情况。甚至SDK中的示例实际上也不允许您忽略CTRL_CLOSE_EVENT
。我在一个小型测试应用程序中进行了尝试,当您关闭窗口并打印消息时会发出蜂鸣声 ,但是该过程仍然会终止。
也许更令人担忧的是,文档使我认为无法避免这种情况:
当用户关闭控制台,注销或关闭系统时,系统会生成CTRL_CLOSE_EVENT
,CTRL_logoFF_EVENT
并CTRL_SHUTDOWN_EVENT
发出信号,以使进程有机会在终止之前进行清理。控制台功能或调用控制台功能的任何C运行时功能在处理上述三个信号中的任何一个期间可能无法可靠地工作。原因是在执行过程信号处理程序之前,可能已调用了部分或全部内部控制台清除例程。
那是我的最后一句话。如果控制台子系统响应于用户试图关闭窗口而 立即 开始自动清理,则事后可能无法将其停止。
(至少现在您了解了问题。也许其他人可以提出解决方案!)