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