任务管理器中的"结束任务"始终设置CloseReason.UserClosing

dan*_*yyy 6 taskmanager kill-process winforms

如果客户试图强制关闭应用程序,我想记录.我知道没有机会抓住进程杀死.但是应该可以通过主窗体关闭事件来了解'CloseReason.TaskManagerClosing'的原因.

但是我在Windows 8.1下做的任何测试我总是得到一个CloseReason.UserClosing原因.但在这种情况下(与法线CloseReason.UserClosing相比)我大约0.2秒运行用户代码后我的程序被杀!

这是Windows 8.1中的新行为吗?

Han*_*ant 8

是的,我明白这一点.是的,这是一个Windows更改,以前版本的任务管理器直接向窗口发送WM_CLOSE通知.我现在看到它发出了与关闭按钮(WM_SYSCOMMAND,SC_CLOSE)关闭窗口时发出的完全相同的命令.或按Alt + F4或使用系统菜单.因此Winforms不再能够区分任务管理器和关闭窗口的用户之间的差异,而是获得CloseReason.UserClosing.

接下来会发生什么,如果你没有足够快地响应关闭命令,那么任务管理器会使用TerminateProcess()立即暗杀您的程序.

请记住,当用户通过任务管理器中止程序时尝试保存数据是一种不好的做法.如果您的程序出现故障,您的用户通常会使用此功能,您不能再真正信任该数据,并且您可能会冒着写垃圾的风险.现在,您的保存代码被中止,部分写入的文件的高赔率或者不再可用的dbase数据更加复杂.

对此没有简单的解决方法,Windows将要修补以恢复旧行为的几率非常接近于零.这是非常保存您的数据在事务的方式,所以如果保存代码被中止,你不破坏有价值的数据很重要.使用File.Replace()获取文件数据,使用dbase事务进行dbase写入.

检测此情况的不完美方法是使用Form.Deactivate和Activate事件.如果您看到Deactivate事件并且FormClosing事件触发,那么另一个程序终止您的事件的合理几率.

但是你处理这个问题的正常方法是常见的,如果用户在没有保存数据的情况下结束程序,那么你会显示一个询问是否保存数据的对话框.任务管理器确保这不会比这更进一步.