I need to stop our Windows service when a PC is powered down into Suspend mode and restart it when the PC is resumed again. What is the proper way to do this?
-
2So why not rephrase your question to *"Why can I not override OnPowerEvent?"* This is clearly the preferred mechanism for dealing with the situation. – J... May 16 '13 at 16:53
-
I figured out why I couldn't override it, I'm an idiot and made the return type void... hahaha. Guess I can edit this question and still make it useful – codewario May 16 '13 at 16:56
-
So, that's the way to go. – Alex Filipovici May 16 '13 at 16:56
-
3Always type `override` and then use code completion – Emond May 16 '13 at 16:58
4 Answers
You should override the ServiceBase.OnPowerEvent Method.
protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus)
{
if (powerStatus.HasFlag(PowerBroadcastStatus.QuerySuspend))
{
}
if (powerStatus.HasFlag(PowerBroadcastStatus.ResumeSuspend))
{
}
return base.OnPowerEvent(powerStatus);
}
The PowerBroadcastStatus Enumeration explains the power statuses.
Also, you'll need to set the ServiceBase.CanHandlePowerEvent Property to true
.
protected override void OnStart(string[] args)
{
this.CanHandlePowerEvent = true;
}

- 31,789
- 6
- 54
- 78
-
1Set CanHandlePowerEvent in service constructor - Cannot change CanStop, CanPauseAndContinue, CanShutdown, CanHandlePowerEvent, or CanHandleSessionChangeEvent property values after the service has been started. – M.Mahdipour Jun 30 '16 at 05:24
-
2Any reason you check the enum with HasFlag, according to this http://referencesource.microsoft.com/#System.ServiceProcess/System/ServiceProcess/PowerBroadcastStatus.cs it isnt marked with flag? – Rand Random Jul 06 '17 at 12:36
-
Using HasFlag() here is definitely wrong! Look into the enum values of PowerBroadcastStatus to see it's not at all suitable as a bit mask. – Nick Sep 16 '19 at 15:20
Comment on Alex Filipovici Answer edited May 16 '13 at 17:05:
CanHandlePowerEvent = true;
must be set in the constructor
Setting it in OnStart()
is too late and causes this Exception:
Service cannot be started. System.InvalidOperationException: Cannot change CanStop, CanPauseAndContinue, CanShutdown, CanHandlePowerEvent, or CanHandleSessionChangeEvent property values after the service has been started.
at System.ServiceProcess.ServiceBase.set_CanHandlePowerEvent(Boolean value)
at foo.bar.OnStart(String[] args)
at System.ServiceProcess.ServiceBase.ServiceQueuedMainCallback(Object state)

- 101
- 6
That's one of the features of Windows service.
Shutdown
The shutdown is done automatically when PC is shut down. No need to do anything. To do any clean up you would need to override ServiceBase
type methods like OnPowerEvent
, sample
public class WinService : ServiceBase
{
protected override void OnStart(string[] args)
{
...
}
protected override void OnStop()
{
...
}
protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus)
{
...
}
}
Start
To start a service automatically you need to set it to ServiceStartMode.Automatic
like here
[RunInstaller(true)]
public class WindowsServiceInstaller : Installer
{
private readonly ServiceProcessInstaller _process;
private readonly ServiceInstaller _service;
public WindowsServiceInstaller()
{
_process = new ServiceProcessInstaller
{
Account = ServiceAccount.LocalSystem
};
_service = new ServiceInstaller
{
ServiceName = "FOO",
StartType = ServiceStartMode.Automatic, // <<<HERE
Description = "Foo service"
};
Installers.Add(_process);
Installers.Add(_service);
}
}

- 35,458
- 16
- 93
- 163
-
Well we have things to do in the event of a shutdown, so we have to perform those first, then call base.OnShutdown(), base.OnStop(), etc. – codewario May 16 '13 at 16:54
Instead of stopping your service could you simply stop the processing with something like...
Microsoft.Win32.SystemEvents.PowerModeChanged += this.SystemEvents_PowerModeChanged;
private void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e)
{
if (e.Mode == PowerModes.Suspend)
{
}
if (e.Mode == PowerModes.Resume)
{
}
}

- 2,848
- 5
- 17
- 18
-
1Note that if you do this you'll need to make sure that the suspend doesn't take too long because the time granted by the service control manager during a regular overload of OnPowerEvent suspend might not be granted here. – Emond May 16 '13 at 16:58
-
@ErnodeWeerd: The event handlers probably get called synchronously from inside `OnPowerEvent`, so I don't think the behavior will be different. – Ben Voigt May 16 '13 at 17:17
-
Oh, you're right. I didn't notice that this event wasn't being provided by `ServiceBase`. – Ben Voigt May 16 '13 at 17:26
-
This code needs a Window running. That might be not what you want in a Windows Service. – Anemoia Jun 28 '16 at 17:12