开发者

How cancel shutdown from a windows service C#

I have a windows service started (written in C# .net2.0).

I want to detect when the computer shutdown/reboot and cancel it. After the cancel I want do some actions and restart windows.

I have tried it, but it not working

using Microsoft.Win32;
partial class MyService: ServiceBase
{
    protected override void OnStart(string[] args)
    {
        SystemEvents.SessionEnd开发者_运维问答ing += new SessionEndingEventHandler(OnSessionEnding);
    }

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

Another test:

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


I wouldn't mess with this. Windows will treat your process like a hung process (unless you go direct to the Win32 API).

My suggestion would be to take note that you're being shutdown, and perhaps schedule the activities to happen on startup?

UPDATE:
I think you're going to get stuck here, because your service won't know why Windows is being shutdown. You'll have an infinite loop:

  • Windows shutdown fires.
  • Service notices, aborts shutdown, launches app.
  • User uses app to continue the shutdown.
  • Window shutdown fires.
  • Service notices......
  • Etc.


My advice would be to write your actions out to a file or the registry e.g.

DoSomething = true
DoSomethingElse = false

Which you could read in OnStart and process.


You could use the shell command shutdown -a to abort the shutdown. I don't know if it's possible to detect a shutdown though...


Finaly I abort the idea of detect and cancel windows shutdown/reboot, But now I want detect only "shutdown -r -t xx" !

Please note the operating system where is running the programme is Windows XP.

I have try it, but I have no ExitCode with WindowsXP:

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


the solution was to detect the shutdown whith a winform : http://msdn.microsoft.com/fr-fr/library/microsoft.win32.systemevents.sessionending%28VS.80%29.aspx

but Windows kill other process before i can detect it, so it's not the better solution!


AbortSystemShutdown might work:

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

Though I agree with Neil that it's probably not a good idea to do this.

Edit: Added sample code

using System.Runtime.InteropServices;

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


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜