如何从Windows服务C#取消关机

时间:2010-04-27 09:43:14

标签: c# windows-services c#-2.0 system-shutdown

我启动了一个Windows服务(用C#.net2.0编写)。

我想检测计算机何时关机/重启并取消它。 取消后我想做一些动作并重新启动窗口。

我已经尝试过,但它无法正常工作

using Microsoft.Win32;
partial class MyService: ServiceBase
{
    protected override void OnStart(string[] args)
    {
        SystemEvents.SessionEnding += new SessionEndingEventHandler(OnSessionEnding);
    }

    private void OnSessionEnding(object sender, SessionEndingEventArgs e)
    {
        e.Cancel = true;
        //Do some work...
    }
}

另一项测试:

partial class MyService: ServiceBase
{
    protected override void OnShutdown()
    {
        //Do some work...
        //base.OnShutdown();
    }
}

6 个答案:

答案 0 :(得分:4)

我不会惹这个。 Windows会将您的进程视为挂起进程(除非您直接使用Win32 API)。

我的建议是注意你正在关机,也许安排活动在启动时进行?

<强>更新
我认为你会被困在这里,因为你的服务不会知道为什么 Windows正在关机。你将有一个无限循环:

  • Windows关闭火灾。
  • 服务通知,中止关机,启动应用程序。
  • 用户使用app继续关机。
  • 关闭窗口。
  • 服务通告......

答案 1 :(得分:1)

我的建议是将你的行动写到文件或注册表中,例如

DoSomething = true
DoSomethingElse = false

您可以在OnStart中阅读并处理。

答案 2 :(得分:1)

AbortSystemShutdown可能会有效:

http://msdn.microsoft.com/en-us/library/aa376630%28VS.85%29.aspx

虽然我同意尼尔的意见,但这样做可能不是一个好主意。

编辑:添加了示例代码

using System.Runtime.InteropServices;

[DllImport("advapi32.dll", SetLastError=true)]
static extern bool AbortSystemShutdown(string lpMachineName);


if (!AbortSystemShutdown("localhost"))
{
    int err = Marshal.GetLastWin32Error();
}        

答案 3 :(得分:1)

您可以使用shell命令shutdown -a中止关闭。我不知道是否可以检测到关机......

答案 4 :(得分:1)

最后我放弃了检测和取消Windows关机/重启的想法, 但现在我只想检测“shutdown -r -t xx”

请注意运行程序的操作系统是Windows XP。

我试过了,但我没有使用WindowsXP的ExitCode:

Process process = new Process();

do
{
    process.StartInfo.FileName = "shutdown.exe";
    process.StartInfo.Arguments = "/a";
    process.Start();
    process.WaitForExit();
    MessageBox.Show(string.Format("ExitCode={0}",process.ExitCode));
    Thread.Sleep(1000);
}
while (process.ExitCode != 0) ;

答案 5 :(得分:1)

解决方案是使用winform检测关闭:http://msdn.microsoft.com/fr-fr/library/microsoft.win32.systemevents.sessionending%28VS.80%29.aspx

但是在我检测到它之前,Windows会杀死其他进程,所以这不是更好的解决方案!