Share via


Detect Windows shutdown from Windows Service

Question

Wednesday, February 17, 2016 8:29 PM

This code detect when a user restarts Windows but does not fire when user does normal windows Shutdown.

Partial code:

const int SERVICE_ACCEPT_PRESHUTDOWN = 0x100;
const int SERVICE_CONTROL_PRESHUTDOWN = 0xf;

            

public mefServiceTest()
        {

            FieldInfo acceptedCommandsFieldInfo =
               typeof(ServiceBase).GetField("acceptedCommands", BindingFlags.Instance | BindingFlags.NonPublic);
            if (acceptedCommandsFieldInfo == null)
            {
                string errormsg = "acceptedCommands field not found";
                System.IO.File.WriteAllText(@"e:\WriteerrText.txt", errormsg);
            }
            int value = (int)acceptedCommandsFieldInfo.GetValue(this);
            acceptedCommandsFieldInfo.SetValue(this, value | SERVICE_ACCEPT_PRESHUTDOWN);
            InitializeComponent();

}

protected override void OnCustomCommand(int command)
        {

            if (command == SERVICE_CONTROL_PRESHUTDOWN)
            {

// do something

            }

       }

All replies (12)

Thursday, February 18, 2016 8:30 PM âś…Answered

I'm not aware of any issues with shut down.  A restart is basically just a shut down followed by a power on.  In newer OSes the restart is a little different but I'm not aware of anyone having issues with shut down.

Having said that, a couple of things come to mind.  Firstly services are on the clock.  If they don't respond fast enough then things go awry.  For a shutdown you have 20 seconds, by default.  For a reboot it is longer (500 seconds in Windows 10).  Hence if your shutdown is taking too long it might fail on shutdown but not on a reboot.

The other thing that comes to mind is that, maybe, your machine isn't actually shutting down. If you're clicking the Shut Down option in the Power menu then it likely is. But starting with Win 8 we have fast boot which could be changing the shut down request to hibernate or something. I've never looked at the shutdown behavior of services in this mode so I cannot confirm.


Wednesday, February 17, 2016 8:55 PM

If your service runs on the computer being shut down, it get's the proper order to close. Wich it should do in a speedy fashion. If you service design requires that you differentiate between ending of service due to shutdown or reboot, the design might be faulty.
There is no reliable way to differentiate between the two. After all a user could just power down via ACPI event (pressing the power button) at the start of the boot sequence. And now a reboot turned into a shutdown.
Or what if a update breaks the boot routine, resulting in it not restarting no mater how hard it tries?

You should always asume that every time the windows shuts down, it will stay shut down.
If you service only saves on stuff like shutdown, there is a serious design problem. After all what if the windows crashes or the user pulls the power cord? If you service works with the network, the network connection might terminate at any moment. Your service must be designed around those possibilities.

If this is about differentiating this from another computer, I am pretty sure the windows logs have some indication when Windows was shutdown/started and if a instant reboot was supposed to happen after the reboot. But again, intention of reboot does not mean a guaranteed reboot.


Wednesday, February 17, 2016 9:08 PM

This service does a few functions and one of them is to advise users when Windows is shutdown or restarted.

So I need to know when a user does a normal Windows shutdown or restart.

I  know the big red button press can't be captured but that should not happen under normal circumstances.


Wednesday, February 17, 2016 9:37 PM

See if the below link helps:

https://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents(v=vs.110).aspx

Paul ~~~~ Microsoft MVP (Visual Basic)


Wednesday, February 17, 2016 9:43 PM

That calls for using a hidden Form and interacting with the desktop, I thought that was being discouraged for services ?


Wednesday, February 17, 2016 10:05 PM | 1 vote

I did not see that in the article. It would appear to be the suggested workaround by Microsoft.

Under normal circumstances of course there would be no reason to have a Windows Form since Services no longer run in the same session as the desktop (and AFAIK it isn't supported).

Paul ~~~~ Microsoft MVP (Visual Basic)


Thursday, February 18, 2016 4:06 PM

I guess the question remains why my code recognizes a Windows Restart but not a normal Windows shutdown.


Thursday, February 18, 2016 5:58 PM

Why are you writing custom code to set the shutdown flag and handle the command specially?  For a regular service set CanShutdown to true and then override OnShutdown.  This gets called when the OS triggers the shutdown process.

If that doesn't work then post the code inside the shutdown method. Note that if the OS has started shutting down then you are limited in what you can do because the order in which services are notified is undefined.  So if you're trying to do something like use the debugger, call a WCF service, etc then there is no guarantee those components will still be running.

Michael Taylor
http://blogs.msmvps.com/p3net


Thursday, February 18, 2016 6:31 PM

I tried the code below:

It writes the file when I do a restart but  not when I click Shut down from the Windows 10 Start Menu in this case.

protected override void OnShutdown()
        {
            // Add your save code here
            // Add your save code here
            StreamWriter str = new StreamWriter("e:\Log.txt", true);
            str.WriteLine("Service stopped due to on" + DateTime.Now.ToString());
            str.Close();

            base.OnShutdown();
        }


Thursday, February 18, 2016 7:33 PM

Unless the Windows Service is being terminated before the OnShutdown event can execute, the only other thing I can think of is that the StreamWriter operation is failing - possibly because of either permissions issues or the inaccessibility of the file source.

Paul ~~~~ Microsoft MVP (Visual Basic)


Thursday, February 18, 2016 8:07 PM

Every function so far works on restart and fails on Shut down.

Is there no way to capture a normal shut down?


Friday, February 19, 2016 6:11 PM

It worked once I used shutdown /s