Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Ensured that exceptions are propogated to the start of the service an…

…d properly handled.
  • Loading branch information...
commit 585e0e46c3e981ee5c09c48a292b5ec7b0a9cb6f 1 parent 2aed1fa
@phatboyg authored
View
15 src/SampleTopshelfService/Program.cs
@@ -18,7 +18,20 @@ class Program
{
static void Main()
{
- HostFactory.Run(x => x.Service<SampleService>());
+ HostFactory.Run(x =>
+ {
+ x.UseLog4Net("log4net.config");
+
+ bool throwOnStart = false;
+ bool throwOnStop = false;
+ bool throwUnhandled = false;
+
+ x.Service(settings => new SampleService(throwOnStart, throwOnStop, throwUnhandled));
+
+ x.AddCommandLineSwitch("throwonstart", v => throwOnStart = v);
+ x.AddCommandLineSwitch("throwonstop", v => throwOnStop = v);
+ x.AddCommandLineSwitch("throwunhandled", v => throwUnhandled = v);
+ });
}
void SansInterface()
View
22 src/SampleTopshelfService/SampleService.cs
@@ -21,8 +21,18 @@ namespace SampleTopshelfService
class SampleService :
ServiceControl
{
+ readonly bool _throwOnStart;
+ readonly bool _throwOnStop;
+ readonly bool _throwUnhandled;
static readonly LogWriter _log = HostLogger.Get<SampleService>();
+ public SampleService(bool throwOnStart, bool throwOnStop, bool throwUnhandled)
+ {
+ _throwOnStart = throwOnStart;
+ _throwOnStop = throwOnStop;
+ _throwUnhandled = throwUnhandled;
+ }
+
public bool Start(HostControl hostControl)
{
_log.Info("SampleService Starting...");
@@ -31,10 +41,19 @@ public bool Start(HostControl hostControl)
Thread.Sleep(1000);
+ if(_throwOnStart)
+ {
+ _log.Info("Throwing as requested");
+ throw new InvalidOperationException("Throw on Start Requested");
+ }
+
ThreadPool.QueueUserWorkItem(x =>
{
Thread.Sleep(3000);
+ if(_throwUnhandled)
+ throw new InvalidOperationException("Throw Unhandled In Random Thread");
+
_log.Info("Requesting stop");
hostControl.Stop();
@@ -48,6 +67,9 @@ public bool Stop(HostControl hostControl)
{
_log.Info("SampleService Stopped");
+ if(_throwOnStop)
+ throw new InvalidOperationException("Throw on Stop Requested!");
+
return true;
}
View
15 src/SampleTopshelfService/SampleTopshelfService.csproj
@@ -67,11 +67,14 @@
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
<CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>
</PropertyGroup>
- <PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v3.5' ">
+ <PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v3.5' ">
<DefineConstants>NET35</DefineConstants>
<OutputPath>bin\$(Configuration)\$(TargetFrameworkVersion)</OutputPath>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="log4net">
+ <HintPath>..\packages\log4net.2.0.0\lib\net40-client\log4net.dll</HintPath>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
@@ -84,6 +87,10 @@
<Compile Include="SampleService.cs" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\Topshelf.Log4Net\Topshelf.Log4Net.csproj">
+ <Project>{0EE64D46-5728-45DB-8D0E-044CE2677FD8}</Project>
+ <Name>Topshelf.Log4Net</Name>
+ </ProjectReference>
<ProjectReference Include="..\Topshelf\Topshelf.csproj">
<Project>{A52AD64D-6455-4A22-8CCF-581851086578}</Project>
<Name>Topshelf</Name>
@@ -92,6 +99,12 @@
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
+ <ItemGroup>
+ <None Include="log4net.config">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ <None Include="packages.config" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
View
38 src/SampleTopshelfService/log4net.config
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<log4net>
+ <appender name="RollingFile"
+ type="log4net.Appender.FileAppender">
+ <file value="SampleTopshelfService.log" />
+ <appendToFile value="false" />
+ <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%-5p %d{hh:mm:ss} %message%newline" />
+ </layout>
+ </appender>
+
+ <appender name="ColoredConsoleAppender"
+ type="log4net.Appender.ColoredConsoleAppender">
+ <mapping>
+ <level value="ERROR" />
+ <foreColor value="Red, HighIntensity" />
+ </mapping>
+ <mapping>
+ <level value="INFO" />
+ <foreColor value="White" />
+ </mapping>
+ <mapping>
+ <level value="DEBUG" />
+ <foreColor value="Cyan" />
+ </mapping>
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%message%newline" />
+ </layout>
+ </appender>
+
+ <!-- Set root logger level to DEBUG and its only appender to Console -->
+ <root>
+ <level value="DEBUG" />
+ <appender-ref ref="RollingFile" />
+ <appender-ref ref="ColoredConsoleAppender" />
+ </root>
+</log4net>
View
4 src/SampleTopshelfService/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="log4net" version="2.0.0" targetFramework="net40-Client" />
+</packages>
View
2  src/SolutionVersion.cs
@@ -9,5 +9,5 @@
[assembly: ComVisibleAttribute(false)]
[assembly: CLSCompliantAttribute(true)]
-[assembly: AssemblyInformationalVersion("3.0.3.fa7ab4")]
+[assembly: AssemblyInformationalVersion("3.0.3.2aed1f")]
View
4 src/Topshelf/Configuration/HostConfigurators/HostConfigurator.cs
@@ -13,10 +13,8 @@
namespace Topshelf.HostConfigurators
{
using System;
- using Configurators;
- public interface HostConfigurator :
- Configurator
+ public interface HostConfigurator
{
/// <summary>
/// Specifies the name of the service as it should be displayed in the service control manager
View
3  src/Topshelf/Configuration/HostConfigurators/HostConfiguratorImpl.cs
@@ -25,7 +25,8 @@ namespace Topshelf.HostConfigurators
using Runtime.Windows;
public class HostConfiguratorImpl :
- HostConfigurator
+ HostConfigurator,
+ Configurator
{
readonly IList<HostBuilderConfigurator> _configurators;
readonly WindowsHostSettings _settings;
View
12 src/Topshelf/Hosts/ConsoleRunHost.cs
@@ -55,6 +55,7 @@ public TopshelfExitCode Run()
return TopshelfExitCode.ServiceAlreadyInstalled;
}
+ bool started = false;
try
{
_log.Debug("Starting up as a console application");
@@ -63,7 +64,10 @@ public TopshelfExitCode Run()
Console.CancelKeyPress += HandleCancelKeyPress;
- _serviceHandle.Start(this);
+ if(!_serviceHandle.Start(this))
+ throw new TopshelfException("The service failed to start (return false).");
+
+ started = true;
_log.InfoFormat("The {0} service is now running, press Control+C to exit.", _settings.ServiceName);
@@ -77,7 +81,8 @@ public TopshelfExitCode Run()
}
finally
{
- StopService();
+ if(started)
+ StopService();
_exit.Close();
(_exit as IDisposable).Dispose();
@@ -132,7 +137,8 @@ void StopService()
{
_log.InfoFormat("Stopping the {0} service", _settings.ServiceName);
- _serviceHandle.Stop(this);
+ if(!_serviceHandle.Stop(this))
+ throw new TopshelfException("The service failed to stop (returned false).");
}
}
catch (Exception ex)
View
18 src/Topshelf/Runtime/Windows/WindowsServiceHost.cs
@@ -49,7 +49,9 @@ public TopshelfExitCode Run()
{
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
- AppDomain.CurrentDomain.UnhandledException += CatchUnhandledException;
+ AppDomain.CurrentDomain.UnhandledException += CatchUnhandledException;
+
+ ExitCode = (int)TopshelfExitCode.Ok;
_log.Info("Starting as a Windows service");
@@ -65,10 +67,9 @@ public TopshelfExitCode Run()
_log.Debug("[Topshelf] Starting up as a windows service application");
- Run(this);
-
- ExitCode = (int)TopshelfExitCode.Ok;
- return TopshelfExitCode.Ok;
+ Run(this);
+
+ return (TopshelfExitCode)Enum.ToObject(typeof(TopshelfExitCode), ExitCode);
}
void HostControl.RequestAdditionalTime(TimeSpan timeRemaining)
@@ -121,7 +122,9 @@ protected override void OnStart(string[] args)
catch (Exception ex)
{
_log.Fatal("The service did not start successfully", ex);
- _log.Fatal(ex);
+ _log.Fatal(ex);
+
+ ExitCode = (int)TopshelfExitCode.StartServiceFailed;
throw;
}
}
@@ -139,7 +142,8 @@ protected override void OnStop()
}
catch (Exception ex)
{
- _log.Fatal("The service did not shut down gracefully", ex);
+ _log.Fatal("The service did not shut down gracefully", ex);
+ ExitCode = (int)TopshelfExitCode.StopServiceFailed;
throw;
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.