当我在控制台窗口中单击ctrl + c时,会引发事件并且应用程序可以执行一些应该在退出之前执行的代码。
然而,当我点击[X]关闭按钮时,事件也会被提升,但是在很短的时间内,我的应用程序被强行关闭 - 当'结束执行'事件仍在进行中时。
是否可以在Windows强制关闭app之前设置更长的超时?
编辑:
我设置:
[DllImport("Kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ControlEventHandler e, bool add);
public delegate void ControlEventHandler(ConsoleEvent consoleEvent);
当我在控制台窗口上单击ctrl + c时,我收到:CTRL_C
,我可以在mu事件处理程序中处理代码。
当我点击[x]关闭按钮时,我收到CTRL_CLOSE
标志,我也可以处理处理程序,但仅限1-2秒。然后控制台windwo disappers ...
答案 0 :(得分:1)
是否可以在Windows强制关闭app之前设置更长的超时?
不幸的是,没有。从Windows Vista开始,在控制台窗口自动关闭之前收到CTRL_CLOSE_EVENT
后,只允许10秒左右的宽限期。如果您在10秒后没有退出处理程序,那么您的进程将被毫不客气地终止。 (显然,如果你早点从处理程序返回,你将不会得到整整10秒。)
据我所知,这是更大的设计策略的一部分,以确保应用程序无法覆盖用户的意愿。 Older versions of the SDK documentation提到了一个对话框,如果进程在某个超时期限内没有响应,则会出现一个对话框,但所有提到的内容都来自current version of the SDK documentation。对话框在Vista中进入MIA,它不再存在。这可能与应用程序无法再阻止系统关闭这一事实有关。
这不会影响您按 Ctrl + C ,因为这会产生不同的信号 - CTRL_C_EVENT
。与 Ctrl + Break 相同,它会引发CTRL_BREAK_EVENT
。但据我在文档中可以看出,CTRL_CLOSE_EVENT
,CTRL_LOGOFF_EVENT
和CTRL_SHUTDOWN_EVENT
只是通知,让您有机会在文档之前进行清理终止。无法阻止终止或延长宽限期。
我只能想到一种解决方法,那就是禁用控制台窗口本身的关闭按钮。我看到你正在使用C#,因此需要一些P / Invoke:
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
static extern bool DeleteMenu(IntPtr hMenu, uint uPosition, uint uFlags);
private const uint MF_BYCOMMAND = 0x0;
private const uint SC_CLOSE = 0xF060;
void DisableConsoleCloseButton()
{
IntPtr hWnd = GetConsoleWindow();
if (hWnd != IntPtr.Zero)
{
IntPtr hMenu = GetSystemMenu(hWnd, false);
if (hMenu != IntPtr.Zero)
{
DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
}
}
}
如果你走这条路,你显然需要为用户提供一些从应用程序中关闭控制台窗口的方法。在Win32-land中,该功能会调用FreeConsole
函数来关闭它,但我敢打赌它包含在一个.NET类中。我太久了,不记得它叫什么。