C# WinForms 托盘应用程序 - 未捕获 Windows 关闭事件

标签 c# .net windows winforms shutdown

我正在编写一个监视状态的程序。它启动主窗口(LoginForm)来询问用户凭据,然后隐藏表单。之后,LoginForm 初始化 NotifyIcon,所有剩余的工作都在隐藏 LoginForm 的情况下完成。我已经在 LoginForm 的 FormClosing 事件中实现了所有清理工作。在正常导出过程中,一切正常。

问题是该程序始终位于托盘中,我往往忘记在关闭窗口之前退出它 - 程序不会保存关闭事件时的状态。

我已经阅读了许多论坛和文档,从我阅读的内容中,无论如何都必须开火。但是看来他们只是不开火。甚至无法在 SessionEnding 中取消关闭(使用愚蠢的 e.Cancel=true) - 程序在到达该位置之前就消失了。

我使自己成为一个小的调试库,将调试信息写入即时闪烁缓存的文件中。我在所有事件中添加了调试消息。当我尝试在Windows中注销用户(与关闭)进行测试时 - 我发现通常不会触发事件,只有程序就消失了。当手动或通过“Taskkill/im”手动退出程序时,我可以捕获,没有事件等异常(exception) - 我看到了所有预期的调试打印输出。更有趣的是 - 有时程序确实会达到关闭事件并在 Windows 关闭期间执行适当的清理工作。

已经浪费了几天。 MS文章中建议的Overriden WNDProc也没有达到WNDProc(以确保首先关闭表格)。尝试代替 FormClosing 事件来覆盖 LoginForm 的 OnClosing - 没有运气。添加了UnhandledException处理程序,Microsoft.win32.Sessionderding,Microsoft.win32.sessioned,form.FormClosing,form.form.formclosed。事件处理程序 - 没有运气。

我怀疑这要么是隐藏表单的问题,要么是仅在关闭期间发生某种异常(资源已处置?)。我怎么能找到为什么会发生这种情况?有没有一些简单的方法来模拟单个应用程序的 Windows 关闭,以便可以在 VS 中进行调试?我尝试了rmtool-由于某种原因,它无法模拟关闭,并且程序忽略了。

更新: program使用system.timers.timer到定期进行轮询服务器进行任何更改。

最佳答案

我对此做了一些研究,基本上,在 Windows XP 之后,他们改变了关闭的处理方式。

您不能使用form_closing事件等可靠地阻止或捕获关闭事件。

您必须使用新的 API 才能执行此操作。这里有一个完整的示例:http://bartdesmet.net/blogs/bart/archive/2006/10/25/Windows-Vista-2D00-ShutdownBlockReasonCreate-in-C_2300_.aspx

您应该能够调用该功能以阻止关闭(显示诸如“保存更改...”之类的消息),然后在后台保存并退出您的应用程序。一旦程序退出,它应该允许 Windows 继续关闭。

关于C# WinForms 托盘应用程序 - 未捕获 Windows 关闭事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34136460/

相关文章:

c# - 判断进程是否为系统进程

c# - .NET 标准库能否以某种方式使用支持 .NET Framework 4.6.1 的 nuget 包

c# - 通过 .net 获取 Active Directory 组中的用户名

java - 32位JVM : Maximum Heap space?

c++ - 使用 QProcessEnvironment 更改 cmd.exe 的 PATH 环境变量

c# - 更新到VS 2015、Azure 2.7,发布失败 'Access to path ... denied'

c# - iTextSharp。为什么单元格背景图像顺时针旋转90度?

c# - 以编程方式安装证书吊销列表 C#

linux - 使用 pscp 在 Raspberry Pi 上传输文件

c# - 如何使用 assembly.CreateInstance 调用非默认构造函数