我正在编写一个监视状态的程序。它启动主窗口(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/