Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#WinForms托盘应用程序-未捕获windows关闭事件_C#_.net_Windows_Winforms_Shutdown - Fatal编程技术网

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

C#WinForms托盘应用程序-未捕获windows关闭事件,c#,.net,windows,winforms,shutdown,C#,.net,Windows,Winforms,Shutdown,我正在写一个监控状态的程序。它启动主窗口(LoginForm)以请求用户凭据,然后隐藏表单。在此之后,LoginForm inits NotifyIcon和所有剩余的工作都将在LoginForm hidden的情况下完成。我已经在LoginForm的FormClosing事件中执行了所有清理工作。在正常的退出过程中,一切都很完美 问题是程序一直放在托盘中,我往往忘记在关闭windows之前退出它-程序不会在关闭事件时保存状态 我读过很多论坛和文档,从中我读到的事件FormClosing/Form

我正在写一个监控状态的程序。它启动主窗口(LoginForm)以请求用户凭据,然后隐藏表单。在此之后,LoginForm inits NotifyIcon和所有剩余的工作都将在LoginForm hidden的情况下完成。我已经在LoginForm的FormClosing事件中执行了所有清理工作。在正常的退出过程中,一切都很完美

问题是程序一直放在托盘中,我往往忘记在关闭windows之前退出它-程序不会在关闭事件时保存状态

我读过很多论坛和文档,从中我读到的事件FormClosing/FormClosed+SessionEnding/SessionEnded无论如何都必须启动。但看起来他们就是不开枪。甚至无法取消SessionEnding中的关机(使用愚蠢的e.cancel=true)-程序未到达该位置即消失

我为自己制作了一个小的调试库,可以通过缓存的即时闪烁将调试信息写入文件。我已将调试消息添加到所有事件中。当我尝试注销Windows中的用户(与关机相同)进行测试时,我通常看不到任何事件被触发,只是程序消失了。当手动或通过“taskkill/IM”退出程序时,我看不到所有预期的调试打印输出。更有趣的是,有时程序确实会发生关闭事件,并在Windows关闭期间执行适当的清理工作

已经在这上面浪费了几天了。按照MS文章中的建议重写WndProc-程序也不会到达WndProc(以确保它在关闭表单之前先到达)。尝试替代FormClosing事件来覆盖LoginForm的丢失-运气不佳。添加了未处理的异常处理程序、Microsoft.Win32.SessionEnding、Microsoft.Win32.SessionEnded、Form.FormClosing、Form.FormClosing事件处理程序-运气不好

我怀疑这可能是隐藏表单的问题,或者只是在关闭期间发生了某种异常(资源已处理?)。我怎样才能找到发生这种情况的原因?是否有一些简单的方法来模拟单个应用程序的Windows关闭,从而使VS中的调试成为可能?我试过RMTool——由于某种原因,它无法模拟关机,程序只是忽略了它


更新:程序使用System.Timers.Timer定期轮询服务器的任何更改。

我认为windows只是简单地配置为自动关闭所有应用程序,因此应用程序没有机会捕捉会话事件,等等:查看或检查计算机上的配置配置>管理模板>系统>关机选项

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

您无法使用表单\关闭事件等可靠地阻止或捕获关闭事件

必须使用新的API才能执行此操作。这里有一个完整的示例:


您应该能够调用函数阻止关闭(显示消息,如“保存更改…”),然后在后台保存并退出应用程序。一旦您的程序退出,它应该允许windows继续关闭。

您是否尝试过在应用程序运行行之后,在程序类中添加清理代码?除非Windows强制终止应用程序,否则程序主方法中的代码将始终运行。这就是我经常尝试的地方。。四处捕捉以捕获并记录所有未处理的异常。@Russ不,将尝试它,谢谢您的想法。@Russ很遗憾,应用程序在应用程序之后没有到达代码。在Main方法中运行。Quick hack--每X分钟保存一次您的状态。或者,在一个已知位置保存一个间歇状态,启动时检查,然后恢复。听起来好像Windows正在彻底终止进程。通常,当Windows关闭时,它会向应用程序发出软关闭信号,以便进行任何和所有清理。如果应用程序执行此操作花费的时间太长,则用户会收到一条消息,表明应用程序正在暂停关闭,并询问您是否要关闭,这将导致暂停关闭的进程无法继续运行。在这一点上,我不知道为什么Windows会对你的应用程序这样做。您是否正在运行任何可能会让Windows感到困惑的非托管代码(P/Invoke)呢?默认情况下,它不会阻止您打开记事本并在中进行更改,这从一开始就防止了关闭began@Ahmad我也检查过这个,不久前禁用了它,只是为了确定一下。行为没有改变。@SLC是的,我保持记事本打开,只是为了避免反复输入密码。它不会对我的应用程序进行任何更改,我的应用程序会在以后运行,然后再运行记事本。该应用程序仍然会消失。所有其他软件都在运行,记事本阻止了实际的注销。看起来很有希望。一旦我测试过这个,我会回来的。用clean project测试过。如果Clean项目从VisualStudio内部运行,则不会获取任何事件。但在VS之外,它会按预期获得所有通知。在我的例子中,看起来像是资源管理不善。那么这个解决方案正是我在完成工作之前防止关机所需要的。谢谢你,SLC。在关闭阻止启用的情况下,我发现另一个窗体正在获取FormClosing事件,原因是=WindowsShutdown,而不是主窗体。没问题。很高兴听到你能捕捉到一些事件,我很担心你将不会有结束事件