C# 检测窗口服务中的关闭

C# 检测窗口服务中的关闭,c#,.net,windows-services,C#,.net,Windows Services,我有一个windows服务,可以获取用户详细信息并将结果保存到日志文本文件中。而且,我的问题是,当我关闭或注销我的系统时,我也想将我关闭系统的时间保存到该日志文件中。但是,我不知道怎么做 我检查了winproc方法以检测关机操作,但我无法在Windows服务上使用它,在Google上发现它只能用于表单。我们如何检测用户已单击关机或注销并执行某些操作。 所以,请给我一些想法或建议 我已将其用于注销,但当我注销系统时会进行日志记录 protected override void OnSessio

我有一个windows服务,可以获取用户详细信息并将结果保存到日志文本文件中。而且,我的问题是,当我关闭或注销我的系统时,我也想将我关闭系统的时间保存到该日志文件中。但是,我不知道怎么做

我检查了winproc方法以检测关机操作,但我无法在Windows服务上使用它,在Google上发现它只能用于表单。我们如何检测用户已单击关机或注销并执行某些操作。 所以,请给我一些想法或建议

我已将其用于注销,但当我注销系统时会进行日志记录

  protected override void OnSessionChange(SessionChangeDescription changeDescription)
  {
     this.RequestAdditionalTime(250000); //gives a 25 second delay on Logoff
     if (changeDescription.Reason == SessionChangeReason.SessionLogoff)
     {
        // Add your save code here
        StreamWriter str = new StreamWriter("D:\\Log.txt", true);
        str.WriteLine("Service stoped due to " + changeDescription.Reason.ToString() + "on" + DateTime.Now.ToString());
        str.Close();
     }
     base.OnSessionChange(changeDescription);
 }
也许你可以用。每隔一段时间(间隔1秒)对有问题的方法进行一次投票,你就可以随心所欲了

您需要API调用。

您应该在服务中重写

// When system shuts down
protected override void OnShutdown()
{
    // Add your save code here
    base.OnShutdown();
}
您可能还希望覆盖

编辑:

如果您真的想收听关机事件,那么这是一个好办法。

对于关机,请覆盖OnShutdown方法:

protected override void OnShutdown()
{
    //your code here
    base.OnShutdown();
}
注销:

首先,将事件处理程序添加到服务构造函数中的Microsoft.Win32.SystemEvents.SessionEnded中:

public MyService()
{
    InitializeComponent;
    Microsoft.Win32.SystemEvents.SessionEnded += new Microsoft.Win32.SessionEndedEventHandler(SystemEvents_SessionEnded);
}
然后添加处理程序:

void SystemEvents_SessionEnded(object sender, Microsoft.Win32.SessionEndedEventArgs e)
{
    //your code here
}
这将捕获任何已结束的会话,包括控制台本身(运行服务的会话)。

Tl;博士 在您的服务集中

CanShutdown=true;
然后覆盖

protectedoverride void OnShutdown()
{
//你的代码在这里
//别忘了调用ServiceBase OnShutdown()
base.onShutton();
}

现在是扩展答案 我知道我是从死里提出来的,但我觉得这很有帮助,希望能给这个话题增加一点内容。我正在实现一个托管在Windows服务中的WCF双工库,遇到这个线程是因为我需要从Windows服务中检测用户何时注销或关闭计算机。我在Windows7和Windows10上使用.NETFramework 4.6.1。就像之前建议的关闭一样,对我有效的是覆盖ServiceBase.OnShutdown()这样:

protected override void OnShutdown()
{
    //Your code here

    //Don't forget to call ServiceBase OnShutdown()
    base.OnShutdown();
}
请记住将以下内容添加到服务的构造函数中,以便捕获关机事件:

CanShutdown = true;
然后,要捕获用户何时注销、锁定屏幕、切换用户等。您只需覆盖
OnSessionChange
方法,如下所示:

protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
    if (changeDescription.Reason == SessionChangeReason.SessionLogoff)
    {
        //Your code here...

        //I called a static method in my WCF inbound interface class to do stuff...
    }

    //Don't forget to call ServiceBase OnSessionChange()
    base.OnSessionChange(changeDescription);
}
当然,请记住将以下内容添加到服务的构造函数中,以便捕获会话更改事件:

CanHandleSessionChangeEvent = true;
免责声明 当Windows再次更改关闭行为时,这个答案可能没有用

计算机关闭时会发生哪些通知? 据我所知,计算机关闭时会出现三种通知:

  • SessionLogoff
  • SessionLock
  • Suspend
前两个由
OnSessionChange()
提供,最后一个由
OnPowerEvent()
提供

当然,自然的选择是
挂起
,但应注意,当计算机被发送到睡眠时,也会发送此通知

如何得到通知? 要获得上面发布的通知,您必须允许服务构造函数中的通知,如下所示:

publicservice1()
{
初始化组件();
CanHandlePoverEvent=真;
CanHandleSessionChangeEvent=true;
}
然后覆盖相应的

受保护的覆盖void OnSessionChange(SessionChangeDescription changeDescription)
{
//做点什么
base.OnSessionChange(changeDescription);
}
受保护的覆盖bool OnPowerEvent(PowerBroadcastStatus powerStatus)
{
//做点什么
返回base.OnPowerEvent(powerStatus);
}
那么ServiceBase.OnShutdown()呢? 嗯,当通过单击电源选项中的“关机”关闭计算机时,不会调用此选项

事实上,正如书中所写

关闭计算机时,计算机实际上进入休眠状态,而不是完全关闭

此外,根据:

使用OnShutdown指定系统关闭时发生的处理

此事件仅在操作系统关闭时发生,而不是在计算机关闭时发生。

当CanShutdown属性为true时,OnShutdown将被重写

因此,如果手动关闭计算机并不能真正关闭计算机,但会使其处于休眠状态,那么什么可以关闭计算机

答案是:

只有在重新启动计算机或其他事件导致计算机处理完全关机时,才会发生完全关机

实际上,我可以通过设置

CanShutdown = true;
并覆盖到OnShutdown

protected override void OnShutdown()
{
    // Do something
    base.OnShutdown();
}
然后重新启动我的电脑



好了,这篇文章够了。我只希望Windows的关闭行为不会很快改变…

@deepu,您有一个合理的时间(我想是30秒)来保存您的状态,如果这还不够,您可以调用。这是哪个操作系统?如果是Vista和Win7,则这是预期的行为,因为服务在会话0中启动,任何用户登录都将启动另一个会话。注销不会在windows服务中触发,您需要让消息泵运行,您可以通过向控制台添加隐藏表单获得该消息AppNot work in windows 10或server 2012/2016。没有触发任何事件。即使添加消息泵也不会触发事件。@jjxtra Windows 10有一个名为“快速启动”的选项,它不调用
OnShutdown
。这两个都不是我要的。设置两个属性,实现两个函数,附加调试器。代码未运行。@jjxtra Windows 10有一个名为“快速启动”的选项,它不调用OnShutdown
protected override void OnShutdown()
{
    // Do something
    base.OnShutdown();
}