1

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.SessionEnding += 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();
    }
}
scrat789
  • 2,961
  • 3
  • 30
  • 26

6 Answers6

4

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.
Neil Barnwell
  • 41,080
  • 29
  • 148
  • 220
  • I can not do my activities on startup because I want lunch a winform application from my windows service when the user loggoff/shutdown/restart. My winform application have a button "Restart Now", and an other "Remind me latter", and do some other work... – scrat789 Apr 27 '10 at 10:07
  • @scrat: Another no-no, windows services aren't built and shouldn't be used for interactivity with a GUI. – James Apr 27 '10 at 10:44
  • @James he *did* say that his service would launch another application, though. – Neil Barnwell Apr 27 '10 at 11:23
  • @Neil, the question says `after the cancel I want to do some actions`. I don't see where he states it should launch another app? Also the infinite loop can easily be avoided by setting a flag... – James Apr 27 '10 at 12:00
  • @James It was in the comment above: "I can not do my activities on startup because **I want lunch a winform application from my windows service** when the user loggoff/shutdown/restart." (emphasis mine). I suppose you could "set a flag" somewhere, but that's ambiguous, and would be some sort of registry setting or a file somewhere. It just feels to me like hack-hack-hacking away to get something working that wasn't necessarily a good idea in the first place. – Neil Barnwell Apr 27 '10 at 14:09
  • @Neil: fair point, but it is *do-able*. Yeah you should only be considering services if you have a process that a) needs to be running continously and b) needs to be invisible c) requires no user interactivity....(IMO) – James Apr 27 '10 at 14:25
  • Thanks for your help, my program work as I want : http://stackoverflow.com/questions/2720125/how-cancel-shutdown-from-a-windows-service-c/2728079#2728079 – scrat789 Apr 28 '10 at 13:12
1

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.

James
  • 80,725
  • 18
  • 167
  • 237
1

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();
}        
Hans Olsson
  • 54,199
  • 15
  • 94
  • 116
  • How can use AbortSystemShutdown Function in C# ? – scrat789 Apr 27 '10 at 10:02
  • Using PInvoke. Here's some information about it http://www.pinvoke.net/default.aspx/advapi32/AbortSystemShutdown.html – Hans Olsson Apr 27 '10 at 10:08
  • Its old but does anyone have a complete code sample for this please? I cant find anything for C# with google. And just don't really understand where to use each of your example's lines in my code. I mean i dont understand where to put the DllImport part and where to use the if() statement to intercept. Thanks in advance. – user3916429 May 22 '15 at 05:03
  • @user3916429 Take a look here: [Platform Invoke Tutorial](https://msdn.microsoft.com/en-us/library/aa288468%28v=vs.71%29.aspx). And the answer to this question looks helpful: http://stackoverflow.com/questions/17620396/tutorial-needed-on-invoking-unmanaged-dll-from-c-net – Hans Olsson May 22 '15 at 08:24
1

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...

Vinz
  • 2,010
  • 1
  • 13
  • 16
1

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) ;
scrat789
  • 2,961
  • 3
  • 30
  • 26
  • I've amended my answer above with actual sample code that should hopefully work so you don't have to start this process. – Hans Olsson Apr 28 '10 at 09:32
  • @ho Windows kill other process before i can detect the shutdown, so it's not the better solution. I decide to detect the timeout windows when "shutdown -r -t xx" stop launch my program at this time. – scrat789 Apr 28 '10 at 13:04
  • The solution for detect the timeout windows after "shutdown -r -t xx" is based on detect the Title of the windows : http://www.pinvoke.net/default.aspx/user32.EnumWindows – scrat789 Apr 28 '10 at 13:09
1

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!

scrat789
  • 2,961
  • 3
  • 30
  • 26