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

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

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

我试过了,但它不起作用

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

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

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

更新:
我想你会被困在这里,因为你的服务不知道为什么 Windows会被关闭。 你将拥有一个无限循环:

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

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

 DoSomething = true DoSomethingElse = false 

您可以在OnStart阅读和处理。

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

最后我放弃了检测和取消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) ; 

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

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

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