【发布时间】:2011-10-11 14:42:58
【问题描述】:
我需要检测 Windows 何时关闭(或重新启动)或用户何时注销。我需要在关闭应用程序之前正确关闭应用程序。 我注意到在 Windows 关闭日时不会引发退出应用程序事件。
但我不确定在关闭之前我应该在哪里执行操作。 谢谢。
【问题讨论】:
标签: c# .net windows winforms system-shutdown
我需要检测 Windows 何时关闭(或重新启动)或用户何时注销。我需要在关闭应用程序之前正确关闭应用程序。 我注意到在 Windows 关闭日时不会引发退出应用程序事件。
但我不确定在关闭之前我应该在哪里执行操作。 谢谢。
【问题讨论】:
标签: c# .net windows winforms system-shutdown
Attach an event handler method 到SystemEvents.SessionEnding event,并且每次引发事件时都会调用您的处理程序方法。如果您愿意,处理此事件将允许您取消挂起的注销或关闭。 (尽管这实际上不像在当前操作系统中听起来那样有效;有关更多信息,请参阅MSDN documentation here。)
如果您不想取消该事件,而只是对其做出适当的反应,则应改为处理 SystemEvents.SessionEnded event。
但是,您必须确保在应用程序关闭时分离您的事件处理程序,因为这两个都是静态事件。
【讨论】:
如果您的代码未在非交互式会话(例如系统服务)中运行,您可以通过pinvoke 使用本机解决方案:
//SM_SHUTTINGDOWN = 0x2000
bool bShutDownPending = GetSystemMetrics(SM_SHUTTINGDOWN) != 0;
【讨论】:
locked 全局布尔变量,或者调用您的自定义事件处理程序。重要的部分是确保它不会“吃掉”太多的 CPU 周期。为此,只需输入Sleep(10);在每个循环中调用。此外,您可以实现一个停止事件以退出该线程。
SystemEvents.SessionEnded 不可用的情况。否则显然使用它。此外,您可能想知道用户是否正在注销,例如,在实施另一个事件时。在这种情况下,这个解决方案更加健壮,根本不需要轮询。
现在你应该使用这样的东西:
private static int WM_QUERYENDSESSION = 0x11;
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (m.Msg==WM_QUERYENDSESSION)
{
MessageBox.Show("queryendsession: this is a logoff, shutdown, or reboot");
}
base.WndProc(ref m);
}
【讨论】: