2011-03-05 87 views
13

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

我检查了winproc方法来检测关机操作,但我无法在窗口服务上使用它,在谷歌搜索中发现它只能用于表单。我们如何检测用户是否已点击关机或注销并执行一些操作。所以,请给我一些想法或建议。当我注销系统

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

回答

13

对于关断,重写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 
} 

这应该捕捉任何结束的会话,包括控制台本身(运行服务的那个)。

+0

注销不起作用,如果我不得不添加更多的东西 – deepu 2011-03-05 06:49:52

+0

@deepu:对不起,我通过忘记对基础OnSessionChange的调用误导了你。看我最近的编辑。 – MPelletier 2011-03-05 06:55:34

+0

谢谢我会检查,是否有任何方法来保持关机,直到该过程完成OnShutdown事件 – deepu 2011-03-05 07:19:41

1

也许你可以使用this我已经用了注销,但在日志条目

而成。每隔一秒钟轮询一次有问题的方法,你就可以做你想做的事情。

您需要RegisterServiceCtrlHandlerEx API调用。

3

你应该在你的服务覆盖OnShutdown

// When system shuts down 
protected override void OnShutdown() 
{ 
    // Add your save code here 
    base.OnShutdown(); 
} 

您可能还需要重写OnStop

// When the user presses stops your service from the control panel 
protected override void OnStop() 
{ 
    // Add your save code here too 
    base.OnStop(); 
} 

编辑:
如果你真的要听关闭事件Microsoft.Win32.SystemEvents.SessionEnding是要走的路。

+0

onshutdown效果很好,但如何把握关机,直到我的过程完成..我可以保持关机,直到我的过程完成怎么可能 – deepu 2011-03-05 06:45:57

+0

@deepu,给你一个合理的时间(我认为30秒)来保存你的状态,如果这还不够你可以调用['RequestAddtionalTime'](http://msdn.microsoft.com/zh-cn/library/system.serviceprocess.servicebase.reques tadditionaltime.aspx)。 – 2011-03-05 07:52:56

+0

谢谢..我可以保持关机,直到我的过程完成RequestAddtionalTime。 – deepu 2011-03-05 07:56:33

6

我知道我把这件事从死里复活了,但我发现它很有帮助,并且希望能为这个话题增加一点点。我正在实现一个WCF双工库,托管在Windows服务中,并且遇到了此线程,因为我需要从Windows服务中检测用户何时注销或关闭计算机。我使用的是Windows 7和Windows 10 .Net框架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; 
+0

这在我看来是最好的答案。有我需要的所有信息用于我的Windows服务。 – JakeStrang 2017-04-10 20:03:33

+0

这些都不是我要求的。设置两个属性,实现两个函数,附加调试器。代码未运行。 – jjxtra 2018-02-18 23:58:26