Skip to content

Commit

Permalink
Added initial support for Service Power events.
Browse files Browse the repository at this point in the history
Renamed variable to match previous naming conventions

Added the mappings to Topshelf types

Updated variable name.

Added comments

Updated log messages
  • Loading branch information
Kristof Mattei authored and phatboyg committed Oct 16, 2016
1 parent 1914188 commit c6ff2ea
Show file tree
Hide file tree
Showing 15 changed files with 264 additions and 6 deletions.
11 changes: 11 additions & 0 deletions src/Topshelf/Configuration/Builders/ControlServiceBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,17 @@ public void SessionChanged(HostControl hostControl, SessionChangedArguments argu
}
}

public bool PowerEvent(HostControl hostControl, PowerEventArguments arguments)
{
var powerEvent = _service as ServicePowerEvent;
if (powerEvent != null)
{
return powerEvent.PowerEvent(hostControl, arguments);
}

return false;
}

public void CustomCommand(HostControl hostControl, int command)
{
var customCommand = _service as ServiceCustomCommand;
Expand Down
17 changes: 15 additions & 2 deletions src/Topshelf/Configuration/Builders/DelegateServiceBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ public class DelegateServiceBuilder<T> :
readonly Func<T, HostControl, bool> _start;
readonly Func<T, HostControl, bool> _stop;
readonly Action<T, HostControl, SessionChangedArguments> _sessionChanged;
readonly Func<T, HostControl, PowerEventArguments, bool> _powerEvent;
readonly Action<T, HostControl, int> _customCommand;

public DelegateServiceBuilder(ServiceFactory<T> serviceFactory, Func<T, HostControl, bool> start,
Func<T, HostControl, bool> stop, Func<T, HostControl, bool> pause, Func<T, HostControl, bool> @continue,
Action<T, HostControl> shutdown, Action<T, HostControl, SessionChangedArguments> sessionChanged,
Func<T, HostControl, PowerEventArguments, bool> powerEvent,
Action<T, HostControl, int> customCommand, ServiceEvents serviceEvents)
{
_serviceFactory = serviceFactory;
Expand All @@ -41,6 +43,7 @@ public DelegateServiceBuilder(ServiceFactory<T> serviceFactory, Func<T, HostCont
_continue = @continue;
_shutdown = shutdown;
_sessionChanged = sessionChanged;
_powerEvent = powerEvent;
_customCommand = customCommand;
_serviceEvents = serviceEvents;
}
Expand All @@ -51,7 +54,7 @@ public ServiceHandle Build(HostSettings settings)
{
T service = _serviceFactory(settings);

return new DelegateServiceHandle(service, _start, _stop, _pause, _continue, _shutdown, _sessionChanged, _customCommand, _serviceEvents);
return new DelegateServiceHandle(service, _start, _stop, _pause, _continue, _shutdown, _sessionChanged, _powerEvent, _customCommand, _serviceEvents);
}
catch (Exception ex)
{
Expand All @@ -70,11 +73,12 @@ class DelegateServiceHandle :
readonly Func<T, HostControl, bool> _start;
readonly Func<T, HostControl, bool> _stop;
readonly Action<T, HostControl, SessionChangedArguments> _sessionChanged;
readonly Func<T, HostControl, PowerEventArguments, bool> _powerEvent;
readonly Action<T, HostControl, int> _customCommand;

public DelegateServiceHandle(T service, Func<T, HostControl, bool> start, Func<T, HostControl, bool> stop,
Func<T, HostControl, bool> pause, Func<T, HostControl, bool> @continue, Action<T, HostControl> shutdown,
Action<T, HostControl, SessionChangedArguments> sessionChanged,
Action<T, HostControl, SessionChangedArguments> sessionChanged, Func<T, HostControl, PowerEventArguments, bool> powerEvent,
Action<T, HostControl, int> customCommand, ServiceEvents serviceEvents)
{
_service = service;
Expand All @@ -84,6 +88,7 @@ public DelegateServiceHandle(T service, Func<T, HostControl, bool> start, Func<T
_continue = @continue;
_shutdown = shutdown;
_sessionChanged = sessionChanged;
_powerEvent = powerEvent;
_customCommand = customCommand;
_serviceEvents = serviceEvents;
}
Expand Down Expand Up @@ -141,6 +146,14 @@ public void SessionChanged(HostControl hostControl, SessionChangedArguments argu
_sessionChanged(_service, hostControl, arguments);
}

public bool PowerEvent(HostControl hostControl, PowerEventArguments arguments)
{
if (_powerEvent != null)
return _powerEvent(_service, hostControl, arguments);

return false;
}

public void CustomCommand(HostControl hostControl, int command)
{
if (_customCommand != null)
Expand Down
14 changes: 13 additions & 1 deletion src/Topshelf/Configuration/ServiceConfiguratorExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,17 @@ public static ServiceConfigurator<T> WhenSessionChanged<T>(this ServiceConfigura

return configurator;
}
}

public static ServiceConfigurator<T> WhenPowerEvent<T>(this ServiceConfigurator<T> configurator,
Func<T, PowerEventArguments, bool> callback)
where T : class
{
if (configurator == null)
throw new ArgumentNullException("configurator");

configurator.WhenPowerEvent((service, control, arguments) => callback(service, arguments));

return configurator;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ public class DelegateServiceConfigurator<T> :

bool _pauseConfigured;
bool _sessionChangeConfigured;
bool _powerEventConfigured;
Action<T, HostControl, SessionChangedArguments> _sessionChanged;
Func<T, HostControl, PowerEventArguments, bool> _powerEvent;
Action<T, HostControl> _shutdown;
bool _shutdownConfigured;
Func<T, HostControl, bool> _start;
Expand All @@ -57,6 +59,8 @@ public IEnumerable<ValidateResult> Validate()
yield return this.Failure("Shutdown", "must not be null if shutdown is allowed");
if (_sessionChangeConfigured && _sessionChanged == null)
yield return this.Failure("SessionChange", "must not be null if session change is allowed");
if (_powerEventConfigured && _powerEvent == null)
yield return this.Failure("PowerEvent", "must not be null if power event reaction is allowed");
if (_customCommandReceivedConfigured && _customCommandReceived == null)
yield return this.Failure("CustomCommand", "must not be null if custom command is allowed");
}
Expand Down Expand Up @@ -100,6 +104,12 @@ public void WhenSessionChanged(Action<T, HostControl, SessionChangedArguments> s
_sessionChanged = sessionChanged;
}

public void WhenPowerEvent(Func<T, HostControl, PowerEventArguments, bool> powerEvent)
{
_powerEventConfigured = true;
_powerEvent = powerEvent;
}

public void WhenCustomCommandReceived(Action<T, HostControl, int> customCommandReceived)
{
_customCommandReceivedConfigured = true;
Expand All @@ -109,7 +119,7 @@ public void WhenCustomCommandReceived(Action<T, HostControl, int> customCommandR
public ServiceBuilder Build()
{
var serviceBuilder = new DelegateServiceBuilder<T>(_factory, _start, _stop, _pause, _continue, _shutdown,
_sessionChanged, _customCommandReceived, ServiceEvents);
_sessionChanged, _powerEvent, _customCommandReceived, ServiceEvents);
return serviceBuilder;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public interface ServiceConfigurator<T> :
void WhenContinued(Func<T, HostControl, bool> @continue);
void WhenShutdown(Action<T, HostControl> shutdown);
void WhenSessionChanged(Action<T, HostControl, SessionChangedArguments> sessionChanged);
void WhenPowerEvent(Func<T, HostControl, PowerEventArguments, bool> powerEvent);
void WhenCustomCommandReceived(Action<T, HostControl, int> customCommandReceived);
}
}
40 changes: 40 additions & 0 deletions src/Topshelf/Hosts/ConsoleRunHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ public ConsoleRunHost(HostSettings settings, HostEnvironment environment, Servic
{
SystemEvents.SessionSwitch += OnSessionChanged;
}

if (settings.CanHandlePowerEvent)
{
SystemEvents.PowerModeChanged += OnPowerModeChanged;
}
}

void OnSessionChanged(object sender, SessionSwitchEventArgs e)
Expand All @@ -62,6 +67,13 @@ void OnSessionChanged(object sender, SessionSwitchEventArgs e)
_serviceHandle.SessionChanged(this, arguments);
}

void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
var arguments = new ConsolePowerEventArguments(e.Mode);

_serviceHandle.PowerEvent(this, arguments);
}


public TopshelfExitCode Run()
{
Expand Down Expand Up @@ -251,5 +263,33 @@ public int SessionId
get { return _sessionId; }
}
}

class ConsolePowerEventArguments :
PowerEventArguments
{
readonly PowerEventCode _eventCode;
public ConsolePowerEventArguments(PowerModes powerMode)
{
switch (powerMode)
{
case PowerModes.Resume:
_eventCode = PowerEventCode.ResumeAutomatic;
break;
case PowerModes.StatusChange:
_eventCode = PowerEventCode.PowerStatusChange;
break;
case PowerModes.Suspend:
_eventCode = PowerEventCode.Suspend;
break;
default:
throw new ArgumentOutOfRangeException(nameof(powerMode), powerMode, null);
}
}

public PowerEventCode EventCode
{
get { return _eventCode; }
}
}
}
}
8 changes: 8 additions & 0 deletions src/Topshelf/Hosts/InstallHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ public bool CanSessionChanged
get { return _settings.CanSessionChanged; }
}

/// <summary>
/// True if the service handles power change events
/// </summary>
public bool CanHandlePowerEvent
{
get { return _settings.CanHandlePowerEvent; }
}

public Credentials Credentials
{
get { return _credentials; }
Expand Down
19 changes: 19 additions & 0 deletions src/Topshelf/PowerEventArguments.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2007-2013 Chris Patterson, Dru Sellers, Travis Smith, et. al.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
namespace Topshelf
{
public interface PowerEventArguments
{
PowerEventCode EventCode { get; }
}
}
62 changes: 62 additions & 0 deletions src/Topshelf/PowerEventCode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2007-2013 Chris Patterson, Dru Sellers, Travis Smith, et. al.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
namespace Topshelf
{
using Hosts;

public enum PowerEventCode
{
/// <summary>
/// The system has requested permission to suspend the computer. An application that grants permission should carry out preparations for the suspension before returning.
/// <remarks>Not supported by <see cref="ConsoleRunHost"/></remarks>
/// </summary>
QuerySuspend = 0,
/// <summary>
/// The system was denied permission to suspend the computer. This status is broadcast if any application or driver denied a previous <see cref="QuerySuspend"/> status.
/// <remarks>Not supported by <see cref="ConsoleRunHost"/></remarks>
/// </summary>
QuerySuspendFailed = 2,
/// <summary>
/// The computer is about to enter a suspended state. This event is typically broadcast when all applications and installable drivers have returned true to a previous QuerySuspend state.
/// </summary>
Suspend = 4,
/// <summary>
/// The system has resumed operation after a critical suspension caused by a failing battery.
/// <remarks>Not supported by <see cref="ConsoleRunHost"/></remarks>
/// </summary>
ResumeCritical = 6,
/// <summary>
/// The system has resumed operation after being suspended.
/// <remarks>Not supported by <see cref="ConsoleRunHost"/></remarks>
/// </summary>
ResumeSuspend = 7,
/// <summary>
/// Battery power is low.
/// <remarks>Not supported by <see cref="ConsoleRunHost"/></remarks>
/// </summary>
BatteryLow = 9,
/// <summary>
/// A change in the power status of the computer is detected, such as a switch from battery power to A/C. The system also broadcasts this event when remaining battery power slips below the threshold specified by the user or if the battery power changes by a specified percentage.
/// </summary>
PowerStatusChange = 10,
/// <summary>
/// An Advanced Power Management (APM) BIOS signaled an APM OEM event.
/// <remarks>Not supported by <see cref="ConsoleRunHost"/></remarks>
/// </summary>
OemEvent = 11,
/// <summary>
/// The computer has woken up automatically to handle an event.
/// </summary>
ResumeAutomatic = 18
}
}
5 changes: 5 additions & 0 deletions src/Topshelf/Runtime/HostSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ public interface HostSettings
/// </summary>
bool CanSessionChanged { get; }

/// <summary>
/// True if the service handles power change events
/// </summary>
bool CanHandlePowerEvent { get; }

/// <summary>
/// The amount of time to wait for the service to start before timing out. Default is 10 seconds.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions src/Topshelf/Runtime/ServiceHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ public interface ServiceHandle :
/// <param name="arguments"></param>
void SessionChanged(HostControl hostControl, SessionChangedArguments arguments);

/// <summary>
/// Handle the power change event
/// </summary>
/// <param name="hostControl"></param>
/// <param name="arguments"></param>
bool PowerEvent(HostControl hostControl, PowerEventArguments arguments);

/// <summary>
/// Handle the custom command
/// </summary>
Expand Down
2 changes: 2 additions & 0 deletions src/Topshelf/Runtime/Windows/WindowsHostSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ public string ServiceName

public bool CanSessionChanged { get; set; }

public bool CanHandlePowerEvent { get; set; }

public TimeSpan StartTimeOut { get; set; }

public TimeSpan StopTimeOut { get; set; }
Expand Down
Loading

0 comments on commit c6ff2ea

Please sign in to comment.