【发布时间】:2015-08-23 04:05:43
【问题描述】:
我的 UI 在 DLL 中。现在,DLL 和使用它的 EXE 都被编译为控制台程序,因此我可以在开发过程中使用 stdout 和 stderr 进行调试和错误报告。其中一件事是我有一个uninit() 函数,可以确保 DLL 没有泄漏内存。
因此,我有一个由 DLL 设置的控制处理程序,以便 CTRL_LOGOFF_EVENT 和 CTRL_SHUTDOWN_EVENT 模拟用户单击“文件”菜单中的“退出”选项:它确实是 PostQuitMessage(0) ,在消息泵返回后发生清理代码。
我知道通常CTRL_SHUTDOWN_EVENT 不能被忽略,并且程序将在处理程序例程返回后终止,无论它返回什么。但是根据MSDN,
请注意,第三方库或 DLL 可以为您的应用程序安装控制台控制处理程序。如果是这样,此处理程序将覆盖默认处理程序,并可能导致应用程序在用户注销时退出。
如果我没看错,这说明由 DLL 安装的控制处理程序会覆盖导致我的程序在处理程序函数返回时退出的处理程序。我错了吗?我的 DLL 的处理程序函数只返回 TRUE,我假设它会进一步阻止任何其他默认值运行,因为上面的简介。
为什么?我注意到奇怪的行为:
在 Windows Vista 上,无论我做什么,程序都会关闭。在这种情况下,我想知道简介是否错误以及终止进程的处理程序是否仍在运行。无论我是否致电ShutdownBlockReasonCreate(),都会发生这种情况。
然而,在 Windows 7 上,我的程序的主窗口似乎获得了 WM_QUERYENDSESSION,并且 Windows 会相应地响应它。这意味着如果我在退出函数中说“不,不要退出(不要调用PostQuitMessage(0))”,Windows 会弹出“应用程序正在阻止关闭”屏幕,说我的主窗口正在阻止关闭。在这种情况下,上面的简介似乎是正确的,因为程序不会在从控制台处理程序返回时退出(如果它甚至被调用!)。
如果我改为说“是,调用PostQuitMessage(0),程序正常退出。但是,我丢失了stdout和stderr上的调试输出,所以我无法判断它是否真的正常退出。调用我的程序作为
new.exe > out.txt 2> err.txt
在cmd.exe 上产生两个空文件;我不知道为什么在系统关闭时输出没有保存(谷歌搜索没有显示任何信息)。
那么有人可以帮我解决一下我的困惑,以便我可以正确地实现这个(包括ShutdownBlockReasonCreate())吗?谢谢。
【问题讨论】: