Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.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# 如何检测Windows关闭或注销_C#_.net_Windows_Winforms_System Shutdown - Fatal编程技术网

C# 如何检测Windows关闭或注销

C# 如何检测Windows关闭或注销,c#,.net,windows,winforms,system-shutdown,C#,.net,Windows,Winforms,System Shutdown,我需要检测Windows何时关闭(或重新启动)或用户何时注销。我需要在关闭应用程序之前正确关闭该应用程序。 我注意到,当Windows关闭时,不会引发退出应用程序事件 我读了这篇文章 但我不确定在关门前我应该在哪里做手术。 谢谢。对于,每次引发事件时都会调用处理程序方法。如果您愿意,处理此事件将允许您取消挂起的注销或关闭。(尽管这在当前操作系统中听起来并不是那么回事;有关更多信息,请参阅。) 如果您不想取消该事件,而只是对其做出适当的反应,那么您应该处理该事件 但是,必须确保在关闭应用程序时分离

我需要检测Windows何时关闭(或重新启动)或用户何时注销。我需要在关闭应用程序之前正确关闭该应用程序。 我注意到,当Windows关闭时,不会引发退出应用程序事件

我读了这篇文章

但我不确定在关门前我应该在哪里做手术。 谢谢。

对于,每次引发事件时都会调用处理程序方法。如果您愿意,处理此事件将允许您取消挂起的注销或关闭。(尽管这在当前操作系统中听起来并不是那么回事;有关更多信息,请参阅。)

如果您不想取消该事件,而只是对其做出适当的反应,那么您应该处理该事件


但是,必须确保在关闭应用程序时分离事件处理程序,因为这两个事件都是静态事件。

如果代码未在非交互式会话(如系统服务)中运行,则可以通过使用本机解决方案:


现在,您应该使用如下内容:

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);
}

这个线程现在可能已经死了,但是如果您的应用程序在关闭已经启动之后启动,会发生什么呢。从技术上来说,你已经错过了这两个项目,这两个项目是否仍然有效。这就是我现在遇到的问题。我的应用程序被设计为保持运行,在关机时,它试图在被windows杀死后重新启动,以准备关机。@Ultratrunks您在这里打了一场失败的仗。应用程序无法可靠地阻止系统关闭,它所能做的只是对此作出反应。@CodyGray根据我的评论,我不寻找任何阻止关闭的东西。我只是想知道。实际上,我现在无意中阻止了关机,因为我的应用程序试图在关机过程开始后启动,它会立即崩溃,并在屏幕上留下一个窗口来阻止关机的发生。这是一个麻烦,所以我想能够查询系统,并问“你是在关闭的中间”,所以我可以采取相应行动。你能详细说明为什么你需要取消事件?您的申请即将关闭。任何东西都不会泄漏。非托管内存是否会保持打开状态?有没有一种方法可以在不关闭或注销的情况下测试这些事件?当然,请记住,这是一种轮询解决方案—无回调,无事件处理—您必须进行检查,直到满足此条件。如何在C#中使用它?我只能在C++中找到@MahmoudAl Qudsi:当然。这只是增加了一点工作量。只需创建一个工作线程,在循环中轮询该值,并使用结果设置一个
lock
ed全局布尔变量,或者调用自定义事件处理程序。重要的部分是确保它不会“消耗”太多的CPU周期。对于这一点,简单地说;在每个周期中调用。此外,您还可以实现一个停止事件来退出该线程。因为有一个异步事件驱动的解决方案,所以您不需要为一个单独的线程和一个CPU循环浪费系统资源。@MahmoudAl Qudsi:您看到我的解释了吗?如果按照我的建议实施,就不会有任何“浪费系统资源”的情况,特别是对.NET应用程序而言。已经有一段时间了,我找不到确切的应用程序,但我提供上述解决方案的原因是.NET的
SystemEvents.Sessioneded
不可用。否则显然要使用它。此外,您可能想知道用户是否在此时注销,例如,在实现另一个事件时。在这种情况下,该解决方案更加健壮,根本不需要轮询。半相关,
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);
}