From efc3e34f6db4f7cb8c16d22f0eb179461a177001 Mon Sep 17 00:00:00 2001
From: NextTurn <45985406+NextTurn@users.noreply.github.com>
Date: Fri, 31 Jul 2020 00:00:00 +0800
Subject: [PATCH] Refactor service configuration
---
.../Configuration/DefaultSettings.cs | 90 -----------
.../Configuration/IWinSWConfiguration.cs | 76 ----------
src/WinSW.Core/Configuration/ServiceConfig.cs | 90 +++++++++++
.../XmlServiceConfig.cs} | 111 +++++++-------
.../Extensions/AbstractWinSWExtension.cs | 2 +-
src/WinSW.Core/Extensions/IWinSWExtension.cs | 4 +-
.../Extensions/WinSWExtensionManager.cs | 12 +-
.../RunawayProcessKillerExtension.cs | 4 +-
src/WinSW.Plugins/SharedDirectoryMapper.cs | 5 +-
src/WinSW.Tests/Configuration/ExamplesTest.cs | 20 +--
src/WinSW.Tests/DownloadConfigTests.cs | 52 +++----
.../Extensions/RunawayProcessKillerTest.cs | 14 +-
.../SharedDirectoryMapperConfigTest.cs | 8 +-
...scriptorTests.cs => ServiceConfigTests.cs} | 129 ++++++++--------
src/WinSW.Tests/Util/CommandLineTestHelper.cs | 18 +--
src/WinSW.Tests/Util/ConfigXmlBuilder.cs | 4 +-
src/WinSW.Tests/Util/ServiceConfigAssert.cs | 34 +++++
.../Util/ServiceDescriptorAssert.cs | 64 --------
src/WinSW/Program.cs | 142 +++++++++---------
src/WinSW/WrapperService.cs | 66 ++++----
20 files changed, 415 insertions(+), 530 deletions(-)
delete mode 100644 src/WinSW.Core/Configuration/DefaultSettings.cs
delete mode 100644 src/WinSW.Core/Configuration/IWinSWConfiguration.cs
create mode 100644 src/WinSW.Core/Configuration/ServiceConfig.cs
rename src/WinSW.Core/{ServiceDescriptor.cs => Configuration/XmlServiceConfig.cs} (86%)
rename src/WinSW.Tests/{ServiceDescriptorTests.cs => ServiceConfigTests.cs} (67%)
create mode 100644 src/WinSW.Tests/Util/ServiceConfigAssert.cs
delete mode 100644 src/WinSW.Tests/Util/ServiceDescriptorAssert.cs
diff --git a/src/WinSW.Core/Configuration/DefaultSettings.cs b/src/WinSW.Core/Configuration/DefaultSettings.cs
deleted file mode 100644
index 33a5f24..0000000
--- a/src/WinSW.Core/Configuration/DefaultSettings.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.ServiceProcess;
-using System.Xml;
-
-namespace WinSW.Configuration
-{
- ///
- /// Default WinSW settings
- ///
- public sealed class DefaultWinSWSettings : IWinSWConfiguration
- {
- public string FullPath => throw new InvalidOperationException(nameof(this.FullPath) + " must be specified.");
-
- public string Id => throw new InvalidOperationException(nameof(this.Id) + " must be specified.");
-
- public string Caption => string.Empty;
-
- public string Description => string.Empty;
-
- public string Executable => throw new InvalidOperationException(nameof(this.Executable) + " must be specified.");
-
- public bool HideWindow => false;
-
- public string ExecutablePath => Process.GetCurrentProcess().MainModule.FileName;
-
- // Installation
- public bool AllowServiceAcountLogonRight => false;
-
- public string? ServiceAccountPassword => null;
-
- public string? ServiceAccountUserName => null;
-
- public Native.SC_ACTION[] FailureActions => new Native.SC_ACTION[0];
-
- public TimeSpan ResetFailureAfter => TimeSpan.FromDays(1);
-
- // Executable management
- public string Arguments => string.Empty;
-
- public string? StartArguments => null;
-
- public string? StopExecutable => null;
-
- public string? StopArguments => null;
-
- public string WorkingDirectory => Path.GetDirectoryName(this.FullPath)!;
-
- public ProcessPriorityClass Priority => ProcessPriorityClass.Normal;
-
- public TimeSpan StopTimeout => TimeSpan.FromSeconds(15);
-
- // Service management
- public ServiceStartMode StartMode => ServiceStartMode.Automatic;
-
- public bool DelayedAutoStart => false;
-
- public bool Preshutdown => false;
-
- public string[] ServiceDependencies => new string[0];
-
- public bool Interactive => false;
-
- // Logging
- public string LogDirectory => Path.GetDirectoryName(this.ExecutablePath)!;
-
- public string LogMode => "append";
-
- public bool OutFileDisabled => false;
-
- public bool ErrFileDisabled => false;
-
- public string OutFilePattern => ".out.log";
-
- public string ErrFilePattern => ".err.log";
-
- // Environment
- public List Downloads => new List(0);
-
- public Dictionary EnvironmentVariables => new Dictionary(0);
-
- // Misc
- public bool BeepOnShutdown => false;
-
- // Extensions
- public XmlNode? ExtensionsConfiguration => null;
- }
-}
diff --git a/src/WinSW.Core/Configuration/IWinSWConfiguration.cs b/src/WinSW.Core/Configuration/IWinSWConfiguration.cs
deleted file mode 100644
index 2d512f1..0000000
--- a/src/WinSW.Core/Configuration/IWinSWConfiguration.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.ServiceProcess;
-using System.Xml;
-
-namespace WinSW.Configuration
-{
- // TODO: Document the parameters && refactor
- public interface IWinSWConfiguration
- {
- string FullPath { get; }
-
- string Id { get; }
-
- string Caption { get; }
-
- string Description { get; }
-
- string Executable { get; }
-
- string ExecutablePath { get; }
-
- bool HideWindow { get; }
-
- // Installation
- bool AllowServiceAcountLogonRight { get; }
-
- string? ServiceAccountPassword { get; }
-
- string? ServiceAccountUserName { get; }
-
- Native.SC_ACTION[] FailureActions { get; }
-
- TimeSpan ResetFailureAfter { get; }
-
- // Executable management
- string Arguments { get; }
-
- string? StartArguments { get; }
-
- string? StopExecutable { get; }
-
- string? StopArguments { get; }
-
- string WorkingDirectory { get; }
-
- ProcessPriorityClass Priority { get; }
-
- TimeSpan StopTimeout { get; }
-
- // Service management
- ServiceStartMode StartMode { get; }
-
- string[] ServiceDependencies { get; }
-
- bool Interactive { get; }
-
- // Logging
- string LogDirectory { get; }
-
- // TODO: replace by enum
- string LogMode { get; }
-
- // Environment
- List Downloads { get; }
-
- Dictionary EnvironmentVariables { get; }
-
- // Misc
- bool BeepOnShutdown { get; }
-
- // Extensions
- XmlNode? ExtensionsConfiguration { get; }
- }
-}
diff --git a/src/WinSW.Core/Configuration/ServiceConfig.cs b/src/WinSW.Core/Configuration/ServiceConfig.cs
new file mode 100644
index 0000000..397aee9
--- /dev/null
+++ b/src/WinSW.Core/Configuration/ServiceConfig.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.ServiceProcess;
+using System.Xml;
+
+namespace WinSW.Configuration
+{
+ ///
+ /// Default WinSW settings
+ ///
+ public abstract class ServiceConfig
+ {
+ public abstract string FullPath { get; }
+
+ public abstract string Id { get; }
+
+ public virtual string Caption => string.Empty;
+
+ public virtual string Description => string.Empty;
+
+ public abstract string Executable { get; }
+
+ public string ExecutablePath => Process.GetCurrentProcess().MainModule.FileName;
+
+ public virtual bool HideWindow => false;
+
+ // Installation
+ public virtual bool AllowServiceAcountLogonRight => false;
+
+ public virtual string? ServiceAccountPassword => null;
+
+ public virtual string? ServiceAccountUserName => null;
+
+ public virtual Native.SC_ACTION[] FailureActions => new Native.SC_ACTION[0];
+
+ public virtual TimeSpan ResetFailureAfter => TimeSpan.FromDays(1);
+
+ // Executable management
+ public virtual string Arguments => string.Empty;
+
+ public virtual string? StartArguments => null;
+
+ public virtual string? StopExecutable => null;
+
+ public virtual string? StopArguments => null;
+
+ public virtual string WorkingDirectory => Path.GetDirectoryName(this.FullPath)!;
+
+ public virtual ProcessPriorityClass Priority => ProcessPriorityClass.Normal;
+
+ public virtual TimeSpan StopTimeout => TimeSpan.FromSeconds(15);
+
+ // Service management
+ public virtual ServiceStartMode StartMode => ServiceStartMode.Automatic;
+
+ public virtual string[] ServiceDependencies => new string[0];
+
+ public virtual bool Interactive => false;
+
+ public virtual bool DelayedAutoStart => false;
+
+ public virtual bool Preshutdown => false;
+
+ // Logging
+ public virtual string LogDirectory => Path.GetDirectoryName(this.ExecutablePath)!;
+
+ public virtual string LogMode => "append";
+
+ public virtual bool OutFileDisabled => false;
+
+ public virtual bool ErrFileDisabled => false;
+
+ public virtual string OutFilePattern => ".out.log";
+
+ public virtual string ErrFilePattern => ".err.log";
+
+ // Environment
+ public virtual List Downloads => new List(0);
+
+ public virtual Dictionary EnvironmentVariables => new Dictionary(0);
+
+ // Misc
+ public virtual bool BeepOnShutdown => false;
+
+ // Extensions
+ public virtual XmlNode? ExtensionsConfiguration => null;
+ }
+}
diff --git a/src/WinSW.Core/ServiceDescriptor.cs b/src/WinSW.Core/Configuration/XmlServiceConfig.cs
similarity index 86%
rename from src/WinSW.Core/ServiceDescriptor.cs
rename to src/WinSW.Core/Configuration/XmlServiceConfig.cs
index fa04a24..2656f21 100644
--- a/src/WinSW.Core/ServiceDescriptor.cs
+++ b/src/WinSW.Core/Configuration/XmlServiceConfig.cs
@@ -15,17 +15,15 @@ namespace WinSW
///
/// In-memory representation of the configuration file.
///
- public class ServiceDescriptor : IWinSWConfiguration
+ public class XmlServiceConfig : ServiceConfig
{
protected readonly XmlDocument dom = new XmlDocument();
private readonly Dictionary environmentVariables;
- internal static ServiceDescriptor? TestDescriptor;
+ internal static XmlServiceConfig? TestConfig;
- public static DefaultWinSWSettings Defaults { get; } = new DefaultWinSWSettings();
-
- public string FullPath { get; }
+ public override string FullPath { get; }
///
/// Where did we find the configuration file?
@@ -41,10 +39,7 @@ namespace WinSW
///
public string BaseName { get; set; }
- // Currently there is no opportunity to alter the executable path
- public virtual string ExecutablePath => Defaults.ExecutablePath;
-
- public ServiceDescriptor()
+ public XmlServiceConfig()
{
string path = this.ExecutablePath;
string baseName = Path.GetFileNameWithoutExtension(path);
@@ -84,7 +79,7 @@ namespace WinSW
}
///
- public ServiceDescriptor(string path)
+ public XmlServiceConfig(string path)
{
if (!File.Exists(path))
{
@@ -122,10 +117,10 @@ namespace WinSW
}
///
- /// Loads descriptor from existing DOM
+ /// Loads config from existing DOM
///
#pragma warning disable CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable.
- public ServiceDescriptor(XmlDocument dom)
+ public XmlServiceConfig(XmlDocument dom)
#pragma warning restore CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable.
{
this.dom = dom;
@@ -133,16 +128,16 @@ namespace WinSW
this.environmentVariables = this.LoadEnvironmentVariables();
}
- internal static ServiceDescriptor Create(string? path)
+ internal static XmlServiceConfig Create(string? path)
{
- return path != null ? new ServiceDescriptor(path) : TestDescriptor ?? new ServiceDescriptor();
+ return path != null ? new XmlServiceConfig(path) : TestConfig ?? new XmlServiceConfig();
}
- public static ServiceDescriptor FromXml(string xml)
+ public static XmlServiceConfig FromXml(string xml)
{
var dom = new XmlDocument();
dom.LoadXml(xml);
- return new ServiceDescriptor(dom);
+ return new XmlServiceConfig(dom);
}
private string SingleElement(string tagName)
@@ -213,31 +208,31 @@ namespace WinSW
///
/// Path to the executable.
///
- public string Executable => this.SingleElement("executable");
+ public override string Executable => this.SingleElement("executable");
- public bool HideWindow => this.SingleBoolElement("hidewindow", Defaults.HideWindow);
+ public override bool HideWindow => this.SingleBoolElement("hidewindow", base.HideWindow);
///
/// Optionally specify a different Path to an executable to shutdown the service.
///
- public string? StopExecutable => this.SingleElement("stopexecutable", true);
+ public override string? StopExecutable => this.SingleElement("stopexecutable", true);
///
/// The arguments element.
///
- public string Arguments
+ public override string Arguments
{
get
{
XmlNode? argumentsNode = this.dom.SelectSingleNode("//arguments");
- return argumentsNode is null ? Defaults.Arguments : Environment.ExpandEnvironmentVariables(argumentsNode.InnerText);
+ return argumentsNode is null ? base.Arguments : Environment.ExpandEnvironmentVariables(argumentsNode.InnerText);
}
}
///
/// The startarguments element.
///
- public string? StartArguments
+ public override string? StartArguments
{
get
{
@@ -249,7 +244,7 @@ namespace WinSW
///
/// The stoparguments element.
///
- public string? StopArguments
+ public override string? StopArguments
{
get
{
@@ -274,12 +269,12 @@ namespace WinSW
public string? PoststopArguments => this.GetArguments(Names.Poststop);
- public string WorkingDirectory
+ public override string WorkingDirectory
{
get
{
var wd = this.SingleElement("workingdirectory", true);
- return string.IsNullOrEmpty(wd) ? Defaults.WorkingDirectory : wd!;
+ return string.IsNullOrEmpty(wd) ? base.WorkingDirectory : wd!;
}
}
@@ -304,7 +299,7 @@ namespace WinSW
}
}
- public XmlNode? ExtensionsConfiguration => this.dom.SelectSingleNode("//extensions");
+ public override XmlNode? ExtensionsConfiguration => this.dom.SelectSingleNode("//extensions");
///
/// Combines the contents of all the elements of the given name,
@@ -351,19 +346,19 @@ namespace WinSW
///
/// LogDirectory is the service wrapper executable directory or the optionally specified logpath element.
///
- public string LogDirectory
+ public override string LogDirectory
{
get
{
XmlNode? loggingNode = this.dom.SelectSingleNode("//logpath");
return loggingNode is null
- ? Defaults.LogDirectory
+ ? base.LogDirectory
: Environment.ExpandEnvironmentVariables(loggingNode.InnerText);
}
}
- public string LogMode
+ public override string LogMode
{
get
{
@@ -385,7 +380,7 @@ namespace WinSW
}
}
- return mode ?? Defaults.LogMode;
+ return mode ?? base.LogMode;
}
}
@@ -399,27 +394,27 @@ namespace WinSW
}
}
- public bool OutFileDisabled => this.SingleBoolElement("outfiledisabled", Defaults.OutFileDisabled);
+ public override bool OutFileDisabled => this.SingleBoolElement("outfiledisabled", base.OutFileDisabled);
- public bool ErrFileDisabled => this.SingleBoolElement("errfiledisabled", Defaults.ErrFileDisabled);
+ public override bool ErrFileDisabled => this.SingleBoolElement("errfiledisabled", base.ErrFileDisabled);
- public string OutFilePattern
+ public override string OutFilePattern
{
get
{
XmlNode? loggingName = this.dom.SelectSingleNode("//outfilepattern");
- return loggingName is null ? Defaults.OutFilePattern : Environment.ExpandEnvironmentVariables(loggingName.InnerText);
+ return loggingName is null ? base.OutFilePattern : Environment.ExpandEnvironmentVariables(loggingName.InnerText);
}
}
- public string ErrFilePattern
+ public override string ErrFilePattern
{
get
{
XmlNode? loggingName = this.dom.SelectSingleNode("//errfilepattern");
- return loggingName is null ? Defaults.ErrFilePattern : Environment.ExpandEnvironmentVariables(loggingName.InnerText);
+ return loggingName is null ? base.ErrFilePattern : Environment.ExpandEnvironmentVariables(loggingName.InnerText);
}
}
@@ -514,14 +509,14 @@ namespace WinSW
///
/// Optionally specified depend services that must start before this service starts.
///
- public string[] ServiceDependencies
+ public override string[] ServiceDependencies
{
get
{
XmlNodeList? nodeList = this.dom.SelectNodes("//depend");
if (nodeList is null)
{
- return Defaults.ServiceDependencies;
+ return base.ServiceDependencies;
}
string[] serviceDependencies = new string[nodeList.Count];
@@ -534,23 +529,23 @@ namespace WinSW
}
}
- public string Id => this.SingleElement("id");
+ public override string Id => this.SingleElement("id");
- public string Caption => this.SingleElement("name", true) ?? Defaults.Caption;
+ public override string Caption => this.SingleElement("name", true) ?? base.Caption;
- public string Description => this.SingleElement("description", true) ?? Defaults.Description;
+ public override string Description => this.SingleElement("description", true) ?? base.Description;
///
/// Start mode of the Service
///
- public ServiceStartMode StartMode
+ public override ServiceStartMode StartMode
{
get
{
string? p = this.SingleElement("startmode", true);
if (p is null)
{
- return Defaults.StartMode;
+ return base.StartMode;
}
try
@@ -575,9 +570,9 @@ namespace WinSW
/// True if the service should be installed with the DelayedAutoStart flag.
/// This setting will be applyed only during the install command and only when the Automatic start mode is configured.
///
- public bool DelayedAutoStart => this.SingleBoolElement("delayedAutoStart", Defaults.DelayedAutoStart);
+ public override bool DelayedAutoStart => this.SingleBoolElement("delayedAutoStart", base.DelayedAutoStart);
- public bool Preshutdown => this.SingleBoolElement("preshutdown", Defaults.Preshutdown);
+ public override bool Preshutdown => this.SingleBoolElement("preshutdown", base.Preshutdown);
public TimeSpan? PreshutdownTimeout
{
@@ -592,30 +587,30 @@ namespace WinSW
/// True if the service should beep when finished on shutdown.
/// This doesn't work on some OSes. See http://msdn.microsoft.com/en-us/library/ms679277%28VS.85%29.aspx
///
- public bool BeepOnShutdown => this.SingleBoolElement("beeponshutdown", Defaults.DelayedAutoStart);
+ public override bool BeepOnShutdown => this.SingleBoolElement("beeponshutdown", base.DelayedAutoStart);
///
/// True if the service can interact with the desktop.
///
- public bool Interactive => this.SingleBoolElement("interactive", Defaults.DelayedAutoStart);
+ public override bool Interactive => this.SingleBoolElement("interactive", base.DelayedAutoStart);
///
/// Environment variable overrides
///
- public Dictionary EnvironmentVariables => new Dictionary(this.environmentVariables);
+ public override Dictionary EnvironmentVariables => new Dictionary(this.environmentVariables);
///
/// List of downloads to be performed by the wrapper before starting
/// a service.
///
- public List Downloads
+ public override List Downloads
{
get
{
XmlNodeList? nodeList = this.dom.SelectNodes("//download");
if (nodeList is null)
{
- return Defaults.Downloads;
+ return base.Downloads;
}
List result = new List(nodeList.Count);
@@ -631,7 +626,7 @@ namespace WinSW
}
}
- public SC_ACTION[] FailureActions
+ public override SC_ACTION[] FailureActions
{
get
{
@@ -661,7 +656,7 @@ namespace WinSW
}
}
- public TimeSpan ResetFailureAfter => this.SingleTimeSpanElement(this.dom, "resetfailure", Defaults.ResetFailureAfter);
+ public override TimeSpan ResetFailureAfter => this.SingleTimeSpanElement(this.dom, "resetfailure", base.ResetFailureAfter);
protected string? GetServiceAccountPart(string subNodeName)
{
@@ -683,16 +678,16 @@ namespace WinSW
protected string? AllowServiceLogon => this.GetServiceAccountPart("allowservicelogon");
- public string? ServiceAccountPassword => this.GetServiceAccountPart("password");
+ public override string? ServiceAccountPassword => this.GetServiceAccountPart("password");
- public string? ServiceAccountUserName => this.GetServiceAccountPart("username");
+ public override string? ServiceAccountUserName => this.GetServiceAccountPart("username");
public bool HasServiceAccount()
{
return this.dom.SelectSingleNode("//serviceaccount") != null;
}
- public bool AllowServiceAcountLogonRight
+ public override bool AllowServiceAcountLogonRight
{
get
{
@@ -711,19 +706,19 @@ namespace WinSW
///
/// Time to wait for the service to gracefully shutdown the executable before we forcibly kill it
///
- public TimeSpan StopTimeout => this.SingleTimeSpanElement(this.dom, "stoptimeout", Defaults.StopTimeout);
+ public override TimeSpan StopTimeout => this.SingleTimeSpanElement(this.dom, "stoptimeout", base.StopTimeout);
///
/// Desired process priority or null if not specified.
///
- public ProcessPriorityClass Priority
+ public override ProcessPriorityClass Priority
{
get
{
string? p = this.SingleElement("priority", true);
if (p is null)
{
- return Defaults.Priority;
+ return base.Priority;
}
return (ProcessPriorityClass)Enum.Parse(typeof(ProcessPriorityClass), p, true);
diff --git a/src/WinSW.Core/Extensions/AbstractWinSWExtension.cs b/src/WinSW.Core/Extensions/AbstractWinSWExtension.cs
index bfc5f4a..691d641 100644
--- a/src/WinSW.Core/Extensions/AbstractWinSWExtension.cs
+++ b/src/WinSW.Core/Extensions/AbstractWinSWExtension.cs
@@ -10,7 +10,7 @@ namespace WinSW.Extensions
public WinSWExtensionDescriptor Descriptor { get; set; }
#pragma warning restore CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable.
- public virtual void Configure(ServiceDescriptor descriptor, XmlNode node)
+ public virtual void Configure(XmlServiceConfig config, XmlNode node)
{
// Do nothing
}
diff --git a/src/WinSW.Core/Extensions/IWinSWExtension.cs b/src/WinSW.Core/Extensions/IWinSWExtension.cs
index a7c1f35..2240367 100644
--- a/src/WinSW.Core/Extensions/IWinSWExtension.cs
+++ b/src/WinSW.Core/Extensions/IWinSWExtension.cs
@@ -25,9 +25,9 @@ namespace WinSW.Extensions
///
/// Init handler. Extension should load it's config during that step
///
- /// Service descriptor
+ /// Service config
/// Configuration node
- void Configure(ServiceDescriptor descriptor, XmlNode node);
+ void Configure(XmlServiceConfig config, XmlNode node);
///
/// Start handler. Called during startup of the service before the child process.
diff --git a/src/WinSW.Core/Extensions/WinSWExtensionManager.cs b/src/WinSW.Core/Extensions/WinSWExtensionManager.cs
index 1ecb90b..1b629ea 100644
--- a/src/WinSW.Core/Extensions/WinSWExtensionManager.cs
+++ b/src/WinSW.Core/Extensions/WinSWExtensionManager.cs
@@ -9,13 +9,13 @@ namespace WinSW.Extensions
{
public Dictionary Extensions { get; }
- public ServiceDescriptor ServiceDescriptor { get; }
+ public XmlServiceConfig ServiceConfig { get; }
private static readonly ILog Log = LogManager.GetLogger(typeof(WinSWExtensionManager));
- public WinSWExtensionManager(ServiceDescriptor serviceDescriptor)
+ public WinSWExtensionManager(XmlServiceConfig serviceConfig)
{
- this.ServiceDescriptor = serviceDescriptor;
+ this.ServiceConfig = serviceConfig;
this.Extensions = new Dictionary();
}
@@ -107,7 +107,7 @@ namespace WinSW.Extensions
/// Loading failure
public void LoadExtensions()
{
- var extensionIds = this.ServiceDescriptor.ExtensionIds;
+ var extensionIds = this.ServiceConfig.ExtensionIds;
foreach (string extensionId in extensionIds)
{
this.LoadExtension(extensionId);
@@ -127,7 +127,7 @@ namespace WinSW.Extensions
throw new ExtensionException(id, "Extension has been already loaded");
}
- XmlNode? extensionsConfig = this.ServiceDescriptor.ExtensionsConfiguration;
+ XmlNode? extensionsConfig = this.ServiceConfig.ExtensionsConfiguration;
XmlElement? configNode = extensionsConfig is null ? null : extensionsConfig.SelectSingleNode("extension[@id='" + id + "'][1]") as XmlElement;
if (configNode is null)
{
@@ -141,7 +141,7 @@ namespace WinSW.Extensions
extension.Descriptor = descriptor;
try
{
- extension.Configure(this.ServiceDescriptor, configNode);
+ extension.Configure(this.ServiceConfig, configNode);
}
catch (Exception ex)
{ // Consider any unexpected exception as fatal
diff --git a/src/WinSW.Plugins/RunawayProcessKillerExtension.cs b/src/WinSW.Plugins/RunawayProcessKillerExtension.cs
index ee1bb01..474a379 100644
--- a/src/WinSW.Plugins/RunawayProcessKillerExtension.cs
+++ b/src/WinSW.Plugins/RunawayProcessKillerExtension.cs
@@ -173,13 +173,13 @@ namespace WinSW.Plugins.RunawayProcessKiller
return parameters.Environment;
}
- public override void Configure(ServiceDescriptor descriptor, XmlNode node)
+ public override void Configure(XmlServiceConfig config, XmlNode node)
{
// We expect the upper logic to process any errors
// TODO: a better parser API for types would be useful
this.Pidfile = XmlHelper.SingleElement(node, "pidfile", false)!;
this.StopTimeout = TimeSpan.FromMilliseconds(int.Parse(XmlHelper.SingleElement(node, "stopTimeout", false)!));
- this.ServiceId = descriptor.Id;
+ this.ServiceId = config.Id;
// TODO: Consider making it documented
var checkWinSWEnvironmentVariable = XmlHelper.SingleElement(node, "checkWinSWEnvironmentVariable", true);
diff --git a/src/WinSW.Plugins/SharedDirectoryMapper.cs b/src/WinSW.Plugins/SharedDirectoryMapper.cs
index df7f649..0fa1925 100644
--- a/src/WinSW.Plugins/SharedDirectoryMapper.cs
+++ b/src/WinSW.Plugins/SharedDirectoryMapper.cs
@@ -27,7 +27,7 @@ namespace WinSW.Plugins.SharedDirectoryMapper
this.entries.Add(config);
}
- public override void Configure(ServiceDescriptor descriptor, XmlNode node)
+ public override void Configure(XmlServiceConfig config, XmlNode node)
{
XmlNodeList? mapNodes = XmlHelper.SingleNode(node, "mapping", false)!.SelectNodes("map");
if (mapNodes != null)
@@ -36,8 +36,7 @@ namespace WinSW.Plugins.SharedDirectoryMapper
{
if (mapNodes[i] is XmlElement mapElement)
{
- var config = SharedDirectoryMapperConfig.FromXml(mapElement);
- this.entries.Add(config);
+ this.entries.Add(SharedDirectoryMapperConfig.FromXml(mapElement));
}
}
}
diff --git a/src/WinSW.Tests/Configuration/ExamplesTest.cs b/src/WinSW.Tests/Configuration/ExamplesTest.cs
index 7e102fb..4e868c0 100644
--- a/src/WinSW.Tests/Configuration/ExamplesTest.cs
+++ b/src/WinSW.Tests/Configuration/ExamplesTest.cs
@@ -15,26 +15,26 @@ namespace WinSW.Tests.Configuration
[Fact]
public void AllOptionsConfigShouldDeclareDefaults()
{
- ServiceDescriptor desc = Load("complete");
+ XmlServiceConfig config = Load("complete");
- Assert.Equal("myapp", desc.Id);
- Assert.Equal("%BASE%\\myExecutable.exe", desc.Executable);
+ Assert.Equal("myapp", config.Id);
+ Assert.Equal("%BASE%\\myExecutable.exe", config.Executable);
- ServiceDescriptorAssert.AssertAllOptionalPropertiesAreDefault(desc);
+ ServiceConfigAssert.AssertAllOptionalPropertiesAreDefault(config);
}
[Fact]
public void MinimalConfigShouldDeclareDefaults()
{
- ServiceDescriptor desc = Load("minimal");
+ XmlServiceConfig config = Load("minimal");
- Assert.Equal("myapp", desc.Id);
- Assert.Equal("%BASE%\\myExecutable.exe", desc.Executable);
+ Assert.Equal("myapp", config.Id);
+ Assert.Equal("%BASE%\\myExecutable.exe", config.Executable);
- ServiceDescriptorAssert.AssertAllOptionalPropertiesAreDefault(desc);
+ ServiceConfigAssert.AssertAllOptionalPropertiesAreDefault(config);
}
- private static ServiceDescriptor Load(string exampleName)
+ private static XmlServiceConfig Load(string exampleName)
{
string directory = Environment.CurrentDirectory;
while (true)
@@ -53,7 +53,7 @@ namespace WinSW.Tests.Configuration
XmlDocument dom = new XmlDocument();
dom.Load(path);
- return new ServiceDescriptor(dom);
+ return new XmlServiceConfig(dom);
}
}
}
diff --git a/src/WinSW.Tests/DownloadConfigTests.cs b/src/WinSW.Tests/DownloadConfigTests.cs
index d60b197..d20863c 100644
--- a/src/WinSW.Tests/DownloadConfigTests.cs
+++ b/src/WinSW.Tests/DownloadConfigTests.cs
@@ -22,10 +22,10 @@ namespace WinSW.Tests
{
// Roundtrip data
Download d = new Download(From, To);
- var sd = ConfigXmlBuilder.Create(this.output)
+ var config = ConfigXmlBuilder.Create(this.output)
.WithDownload(d)
- .ToServiceDescriptor(true);
- var loaded = this.GetSingleEntry(sd);
+ .ToServiceConfig(true);
+ var loaded = this.GetSingleEntry(config);
// Check default values
Assert.False(loaded.FailOnError);
@@ -40,10 +40,10 @@ namespace WinSW.Tests
{
// Roundtrip data
Download d = new Download(From, To, true, Download.AuthType.Basic, "aUser", "aPassword", true);
- var sd = ConfigXmlBuilder.Create(this.output)
+ var config = ConfigXmlBuilder.Create(this.output)
.WithDownload(d)
- .ToServiceDescriptor(true);
- var loaded = this.GetSingleEntry(sd);
+ .ToServiceConfig(true);
+ var loaded = this.GetSingleEntry(config);
// Check default values
Assert.True(loaded.FailOnError);
@@ -58,10 +58,10 @@ namespace WinSW.Tests
{
// Roundtrip data
Download d = new Download(From, To, false, Download.AuthType.Sspi);
- var sd = ConfigXmlBuilder.Create(this.output)
+ var config = ConfigXmlBuilder.Create(this.output)
.WithDownload(d)
- .ToServiceDescriptor(true);
- var loaded = this.GetSingleEntry(sd);
+ .ToServiceConfig(true);
+ var loaded = this.GetSingleEntry(config);
// Check default values
Assert.False(loaded.FailOnError);
@@ -107,11 +107,11 @@ namespace WinSW.Tests
{
Download d = new Download(From, To, failOnError);
- var sd = ConfigXmlBuilder.Create(this.output)
+ var config = ConfigXmlBuilder.Create(this.output)
.WithDownload(d)
- .ToServiceDescriptor(true);
+ .ToServiceConfig(true);
- var loaded = this.GetSingleEntry(sd);
+ var loaded = this.GetSingleEntry(config);
Assert.Equal(From, loaded.From);
Assert.Equal(To, loaded.To);
Assert.Equal(failOnError, loaded.FailOnError);
@@ -123,11 +123,11 @@ namespace WinSW.Tests
[Fact]
public void Download_FailOnError_Undefined()
{
- var sd = ConfigXmlBuilder.Create(this.output)
+ var config = ConfigXmlBuilder.Create(this.output)
.WithRawEntry("")
- .ToServiceDescriptor(true);
+ .ToServiceConfig(true);
- var loaded = this.GetSingleEntry(sd);
+ var loaded = this.GetSingleEntry(config);
Assert.False(loaded.FailOnError);
}
@@ -138,10 +138,10 @@ namespace WinSW.Tests
[InlineData("Sspi")]
public void AuthType_Is_CaseInsensitive(string authType)
{
- var sd = ConfigXmlBuilder.Create(this.output)
+ var config = ConfigXmlBuilder.Create(this.output)
.WithRawEntry("")
- .ToServiceDescriptor(true);
- var loaded = this.GetSingleEntry(sd);
+ .ToServiceConfig(true);
+ var loaded = this.GetSingleEntry(config);
Assert.Equal(Download.AuthType.Sspi, loaded.Auth);
}
@@ -149,11 +149,11 @@ namespace WinSW.Tests
public void Should_Fail_On_Unsupported_AuthType()
{
// TODO: will need refactoring once all fields are being parsed on startup
- var sd = ConfigXmlBuilder.Create(this.output)
+ var config = ConfigXmlBuilder.Create(this.output)
.WithRawEntry("")
- .ToServiceDescriptor(true);
+ .ToServiceConfig(true);
- var e = Assert.Throws(() => this.GetSingleEntry(sd));
+ var e = Assert.Throws(() => this.GetSingleEntry(config));
Assert.StartsWith("Cannot parse Enum value from string 'digest'", e.Message);
}
@@ -187,19 +187,19 @@ namespace WinSW.Tests
}
}
- private Download GetSingleEntry(ServiceDescriptor sd)
+ private Download GetSingleEntry(XmlServiceConfig config)
{
- var downloads = sd.Downloads.ToArray();
+ var downloads = config.Downloads.ToArray();
return Assert.Single(downloads);
}
private void AssertInitializationFails(Download download, string expectedMessagePart = null)
{
- var sd = ConfigXmlBuilder.Create(this.output)
+ var config = ConfigXmlBuilder.Create(this.output)
.WithDownload(download)
- .ToServiceDescriptor(true);
+ .ToServiceConfig(true);
- var e = Assert.Throws(() => this.GetSingleEntry(sd));
+ var e = Assert.Throws(() => this.GetSingleEntry(config));
Assert.StartsWith(expectedMessagePart, e.Message);
}
}
diff --git a/src/WinSW.Tests/Extensions/RunawayProcessKillerTest.cs b/src/WinSW.Tests/Extensions/RunawayProcessKillerTest.cs
index ee19f06..6316e02 100644
--- a/src/WinSW.Tests/Extensions/RunawayProcessKillerTest.cs
+++ b/src/WinSW.Tests/Extensions/RunawayProcessKillerTest.cs
@@ -12,7 +12,7 @@ namespace WinSW.Tests.Extensions
{
public class RunawayProcessKillerExtensionTest : ExtensionTestBase
{
- private readonly ServiceDescriptor testServiceDescriptor;
+ private readonly XmlServiceConfig serviceConfig;
private readonly string testExtension = GetExtensionClassNameWithAssembly(typeof(RunawayProcessKillerExtension));
@@ -37,13 +37,13 @@ $@"
";
- this.testServiceDescriptor = ServiceDescriptor.FromXml(seedXml);
+ this.serviceConfig = XmlServiceConfig.FromXml(seedXml);
}
[Fact]
public void LoadExtensions()
{
- WinSWExtensionManager manager = new WinSWExtensionManager(this.testServiceDescriptor);
+ WinSWExtensionManager manager = new WinSWExtensionManager(this.serviceConfig);
manager.LoadExtensions();
_ = Assert.Single(manager.Extensions);
@@ -57,7 +57,7 @@ $@"
[Fact]
public void StartStopExtension()
{
- WinSWExtensionManager manager = new WinSWExtensionManager(this.testServiceDescriptor);
+ WinSWExtensionManager manager = new WinSWExtensionManager(this.serviceConfig);
manager.LoadExtensions();
manager.FireOnWrapperStarted();
manager.FireBeforeWrapperStopped();
@@ -84,10 +84,10 @@ $@"
{
// Generate extension and ensure that the roundtrip is correct
var pidfile = Path.Combine(tmpDir, "process.pid");
- var sd = ConfigXmlBuilder.Create(this.output, id: winswId)
+ var config = ConfigXmlBuilder.Create(this.output, id: winswId)
.WithRunawayProcessKiller(new RunawayProcessKillerExtension(pidfile), extensionId)
- .ToServiceDescriptor();
- WinSWExtensionManager manager = new WinSWExtensionManager(sd);
+ .ToServiceConfig();
+ WinSWExtensionManager manager = new WinSWExtensionManager(config);
manager.LoadExtensions();
var extension = manager.Extensions[extensionId] as RunawayProcessKillerExtension;
Assert.NotNull(extension);
diff --git a/src/WinSW.Tests/Extensions/SharedDirectoryMapperConfigTest.cs b/src/WinSW.Tests/Extensions/SharedDirectoryMapperConfigTest.cs
index 7a87694..7271aac 100644
--- a/src/WinSW.Tests/Extensions/SharedDirectoryMapperConfigTest.cs
+++ b/src/WinSW.Tests/Extensions/SharedDirectoryMapperConfigTest.cs
@@ -6,7 +6,7 @@ namespace WinSW.Tests.Extensions
{
public class SharedDirectoryMapperConfigTest : ExtensionTestBase
{
- private readonly ServiceDescriptor testServiceDescriptor;
+ private readonly XmlServiceConfig serviceConfig;
private readonly string testExtension = GetExtensionClassNameWithAssembly(typeof(SharedDirectoryMapper));
@@ -35,13 +35,13 @@ $@"
";
- this.testServiceDescriptor = ServiceDescriptor.FromXml(seedXml);
+ this.serviceConfig = XmlServiceConfig.FromXml(seedXml);
}
[Fact]
public void LoadExtensions()
{
- WinSWExtensionManager manager = new WinSWExtensionManager(this.testServiceDescriptor);
+ WinSWExtensionManager manager = new WinSWExtensionManager(this.serviceConfig);
manager.LoadExtensions();
Assert.Equal(2, manager.Extensions.Count);
}
@@ -49,7 +49,7 @@ $@"
[Fact]
public void StartStopExtension()
{
- WinSWExtensionManager manager = new WinSWExtensionManager(this.testServiceDescriptor);
+ WinSWExtensionManager manager = new WinSWExtensionManager(this.serviceConfig);
manager.LoadExtensions();
manager.FireOnWrapperStarted();
manager.FireBeforeWrapperStopped();
diff --git a/src/WinSW.Tests/ServiceDescriptorTests.cs b/src/WinSW.Tests/ServiceConfigTests.cs
similarity index 67%
rename from src/WinSW.Tests/ServiceDescriptorTests.cs
rename to src/WinSW.Tests/ServiceConfigTests.cs
index beaacb7..3f9fd7a 100644
--- a/src/WinSW.Tests/ServiceDescriptorTests.cs
+++ b/src/WinSW.Tests/ServiceConfigTests.cs
@@ -8,7 +8,7 @@ using Xunit.Abstractions;
namespace WinSW.Tests
{
- public class ServiceDescriptorTests
+ public class ServiceConfigTests
{
private const string ExpectedWorkingDirectory = @"Z:\Path\SubPath";
private const string Username = "User";
@@ -18,9 +18,9 @@ namespace WinSW.Tests
private readonly ITestOutputHelper output;
- private ServiceDescriptor extendedServiceDescriptor;
+ private XmlServiceConfig extendedServiceConfig;
- public ServiceDescriptorTests(ITestOutputHelper output)
+ public ServiceConfigTests(ITestOutputHelper output)
{
this.output = output;
@@ -40,13 +40,13 @@ $@"
{ExpectedWorkingDirectory}
C:\logs
";
- this.extendedServiceDescriptor = ServiceDescriptor.FromXml(seedXml);
+ this.extendedServiceConfig = XmlServiceConfig.FromXml(seedXml);
}
[Fact]
public void DefaultStartMode()
{
- Assert.Equal(ServiceStartMode.Automatic, this.extendedServiceDescriptor.StartMode);
+ Assert.Equal(ServiceStartMode.Automatic, this.extendedServiceConfig.StartMode);
}
[Fact]
@@ -70,8 +70,8 @@ $@"
C:\logs
";
- this.extendedServiceDescriptor = ServiceDescriptor.FromXml(seedXml);
- _ = Assert.Throws(() => this.extendedServiceDescriptor.StartMode);
+ this.extendedServiceConfig = XmlServiceConfig.FromXml(seedXml);
+ _ = Assert.Throws(() => this.extendedServiceConfig.StartMode);
}
[Fact]
@@ -95,48 +95,45 @@ $@"
C:\logs
";
- this.extendedServiceDescriptor = ServiceDescriptor.FromXml(seedXml);
- Assert.Equal(ServiceStartMode.Manual, this.extendedServiceDescriptor.StartMode);
+ this.extendedServiceConfig = XmlServiceConfig.FromXml(seedXml);
+ Assert.Equal(ServiceStartMode.Manual, this.extendedServiceConfig.StartMode);
}
[Fact]
public void VerifyWorkingDirectory()
{
- Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + this.extendedServiceDescriptor.WorkingDirectory);
- Assert.Equal(ExpectedWorkingDirectory, this.extendedServiceDescriptor.WorkingDirectory);
+ Assert.Equal(ExpectedWorkingDirectory, this.extendedServiceConfig.WorkingDirectory);
}
[Fact]
public void VerifyServiceLogonRight()
{
- Assert.True(this.extendedServiceDescriptor.AllowServiceAcountLogonRight);
+ Assert.True(this.extendedServiceConfig.AllowServiceAcountLogonRight);
}
[Fact]
public void VerifyUsername()
{
- Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + this.extendedServiceDescriptor.WorkingDirectory);
- Assert.Equal(Domain + "\\" + Username, this.extendedServiceDescriptor.ServiceAccountUserName);
+ Assert.Equal(Domain + "\\" + Username, this.extendedServiceConfig.ServiceAccountUserName);
}
[Fact]
public void VerifyPassword()
{
- Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + this.extendedServiceDescriptor.WorkingDirectory);
- Assert.Equal(Password, this.extendedServiceDescriptor.ServiceAccountPassword);
+ Assert.Equal(Password, this.extendedServiceConfig.ServiceAccountPassword);
}
[Fact]
public void Priority()
{
- var sd = ServiceDescriptor.FromXml("testnormal");
- Assert.Equal(ProcessPriorityClass.Normal, sd.Priority);
+ var config = XmlServiceConfig.FromXml("testnormal");
+ Assert.Equal(ProcessPriorityClass.Normal, config.Priority);
- sd = ServiceDescriptor.FromXml("testidle");
- Assert.Equal(ProcessPriorityClass.Idle, sd.Priority);
+ config = XmlServiceConfig.FromXml("testidle");
+ Assert.Equal(ProcessPriorityClass.Idle, config.Priority);
- sd = ServiceDescriptor.FromXml("test");
- Assert.Equal(ProcessPriorityClass.Normal, sd.Priority);
+ config = XmlServiceConfig.FromXml("test");
+ Assert.Equal(ProcessPriorityClass.Normal, config.Priority);
}
[Fact]
@@ -145,9 +142,9 @@ $@"
const string seedXml = ""
+ "60sec"
+ "";
- var serviceDescriptor = ServiceDescriptor.FromXml(seedXml);
+ var config = XmlServiceConfig.FromXml(seedXml);
- Assert.Equal(TimeSpan.FromSeconds(60), serviceDescriptor.StopTimeout);
+ Assert.Equal(TimeSpan.FromSeconds(60), config.StopTimeout);
}
[Fact]
@@ -156,9 +153,9 @@ $@"
const string seedXml = ""
+ "10min"
+ "";
- var serviceDescriptor = ServiceDescriptor.FromXml(seedXml);
+ var config = XmlServiceConfig.FromXml(seedXml);
- Assert.Equal(TimeSpan.FromMinutes(10), serviceDescriptor.StopTimeout);
+ Assert.Equal(TimeSpan.FromMinutes(10), config.StopTimeout);
}
[Fact]
@@ -167,9 +164,9 @@ $@"
const string seedXml = ""
+ "MyTestApp"
+ "";
- var serviceDescriptor = ServiceDescriptor.FromXml(seedXml);
+ var config = XmlServiceConfig.FromXml(seedXml);
- Assert.Equal("MyTestApp", serviceDescriptor.LogName);
+ Assert.Equal("MyTestApp", config.LogName);
}
[Fact]
@@ -178,9 +175,9 @@ $@"
const string seedXml = ""
+ "true"
+ "";
- var serviceDescriptor = ServiceDescriptor.FromXml(seedXml);
+ var config = XmlServiceConfig.FromXml(seedXml);
- Assert.True(serviceDescriptor.OutFileDisabled);
+ Assert.True(config.OutFileDisabled);
}
[Fact]
@@ -189,9 +186,9 @@ $@"
const string seedXml = ""
+ "true"
+ "";
- var serviceDescriptor = ServiceDescriptor.FromXml(seedXml);
+ var config = XmlServiceConfig.FromXml(seedXml);
- Assert.True(serviceDescriptor.ErrFileDisabled);
+ Assert.True(config.ErrFileDisabled);
}
[Fact]
@@ -200,9 +197,9 @@ $@"
const string seedXml = ""
+ ".out.test.log"
+ "";
- var serviceDescriptor = ServiceDescriptor.FromXml(seedXml);
+ var config = XmlServiceConfig.FromXml(seedXml);
- Assert.Equal(".out.test.log", serviceDescriptor.OutFilePattern);
+ Assert.Equal(".out.test.log", config.OutFilePattern);
}
[Fact]
@@ -211,9 +208,9 @@ $@"
const string seedXml = ""
+ ".err.test.log"
+ "";
- var serviceDescriptor = ServiceDescriptor.FromXml(seedXml);
+ var config = XmlServiceConfig.FromXml(seedXml);
- Assert.Equal(".err.test.log", serviceDescriptor.ErrFilePattern);
+ Assert.Equal(".err.test.log", config.ErrFilePattern);
}
[Fact]
@@ -227,10 +224,10 @@ $@"
+ ""
+ "";
- var serviceDescriptor = ServiceDescriptor.FromXml(seedXml);
- serviceDescriptor.BaseName = "service";
+ var config = XmlServiceConfig.FromXml(seedXml);
+ config.BaseName = "service";
- var logHandler = serviceDescriptor.LogHandler as SizeBasedRollingLogAppender;
+ var logHandler = config.LogHandler as SizeBasedRollingLogAppender;
Assert.NotNull(logHandler);
Assert.Equal(112 * 1024, logHandler.SizeThreshold);
Assert.Equal(113, logHandler.FilesToKeep);
@@ -247,10 +244,10 @@ $@"
+ ""
+ "";
- var serviceDescriptor = ServiceDescriptor.FromXml(seedXml);
- serviceDescriptor.BaseName = "service";
+ var config = XmlServiceConfig.FromXml(seedXml);
+ config.BaseName = "service";
- var logHandler = serviceDescriptor.LogHandler as TimeBasedRollingLogAppender;
+ var logHandler = config.LogHandler as TimeBasedRollingLogAppender;
Assert.NotNull(logHandler);
Assert.Equal(7, logHandler.Period);
Assert.Equal("log pattern", logHandler.Pattern);
@@ -268,10 +265,10 @@ $@"
+ ""
+ "";
- var serviceDescriptor = ServiceDescriptor.FromXml(seedXml);
- serviceDescriptor.BaseName = "service";
+ var config = XmlServiceConfig.FromXml(seedXml);
+ config.BaseName = "service";
- var logHandler = serviceDescriptor.LogHandler as RollingSizeTimeLogAppender;
+ var logHandler = config.LogHandler as RollingSizeTimeLogAppender;
Assert.NotNull(logHandler);
Assert.Equal(10240 * 1024, logHandler.SizeThreshold);
Assert.Equal("yyyy-MM-dd", logHandler.FilePattern);
@@ -289,8 +286,8 @@ $@"
+ "true1"
+ ""
+ "";
- var serviceDescriptor = ServiceDescriptor.FromXml(seedXml);
- Assert.False(serviceDescriptor.AllowServiceAcountLogonRight);
+ var config = XmlServiceConfig.FromXml(seedXml);
+ Assert.False(config.AllowServiceAcountLogonRight);
}
[Fact]
@@ -303,22 +300,22 @@ $@"
+ "" + Password + ""
+ ""
+ "";
- var serviceDescriptor = ServiceDescriptor.FromXml(seedXml);
- Assert.False(serviceDescriptor.AllowServiceAcountLogonRight);
+ var config = XmlServiceConfig.FromXml(seedXml);
+ Assert.False(config.AllowServiceAcountLogonRight);
}
[Fact]
public void VerifyResetFailureAfter()
{
- var sd = ConfigXmlBuilder.Create(this.output).WithTag("resetfailure", "75 sec").ToServiceDescriptor(true);
- Assert.Equal(TimeSpan.FromSeconds(75), sd.ResetFailureAfter);
+ var config = ConfigXmlBuilder.Create(this.output).WithTag("resetfailure", "75 sec").ToServiceConfig(true);
+ Assert.Equal(TimeSpan.FromSeconds(75), config.ResetFailureAfter);
}
[Fact]
public void VerifyStopTimeout()
{
- var sd = ConfigXmlBuilder.Create(this.output).WithTag("stoptimeout", "35 secs").ToServiceDescriptor(true);
- Assert.Equal(TimeSpan.FromSeconds(35), sd.StopTimeout);
+ var config = ConfigXmlBuilder.Create(this.output).WithTag("stoptimeout", "35 secs").ToServiceConfig(true);
+ Assert.Equal(TimeSpan.FromSeconds(35), config.StopTimeout);
}
///
@@ -327,8 +324,8 @@ $@"
[Fact]
public void Arguments_LegacyParam()
{
- var sd = ConfigXmlBuilder.Create(this.output).WithTag("arguments", "arg").ToServiceDescriptor(true);
- Assert.Equal("arg", sd.Arguments);
+ var config = ConfigXmlBuilder.Create(this.output).WithTag("arguments", "arg").ToServiceConfig(true);
+ Assert.Equal("arg", config.Arguments);
}
[Theory]
@@ -342,8 +339,8 @@ $@"
bldr = bldr.WithDelayedAutoStart();
}
- var sd = bldr.ToServiceDescriptor();
- Assert.Equal(enabled, sd.DelayedAutoStart);
+ var config = bldr.ToServiceConfig();
+ Assert.Equal(enabled, config.DelayedAutoStart);
}
[Fact]
@@ -378,16 +375,16 @@ $@"
";
- ServiceDescriptor descriptor = ServiceDescriptor.FromXml(seedXml);
+ XmlServiceConfig config = XmlServiceConfig.FromXml(seedXml);
- Assert.Equal(prestartExecutable, descriptor.PrestartExecutable);
- Assert.Equal(prestartArguments, descriptor.PrestartArguments);
- Assert.Equal(poststartExecutable, descriptor.PoststartExecutable);
- Assert.Equal(poststartArguments, descriptor.PoststartArguments);
- Assert.Equal(prestopExecutable, descriptor.PrestopExecutable);
- Assert.Equal(prestopArguments, descriptor.PrestopArguments);
- Assert.Equal(poststopExecutable, descriptor.PoststopExecutable);
- Assert.Equal(poststopArguments, descriptor.PoststopArguments);
+ Assert.Equal(prestartExecutable, config.PrestartExecutable);
+ Assert.Equal(prestartArguments, config.PrestartArguments);
+ Assert.Equal(poststartExecutable, config.PoststartExecutable);
+ Assert.Equal(poststartArguments, config.PoststartArguments);
+ Assert.Equal(prestopExecutable, config.PrestopExecutable);
+ Assert.Equal(prestopArguments, config.PrestopArguments);
+ Assert.Equal(poststopExecutable, config.PoststopExecutable);
+ Assert.Equal(poststopArguments, config.PoststopArguments);
}
}
}
diff --git a/src/WinSW.Tests/Util/CommandLineTestHelper.cs b/src/WinSW.Tests/Util/CommandLineTestHelper.cs
index 8a91fdd..91feed7 100644
--- a/src/WinSW.Tests/Util/CommandLineTestHelper.cs
+++ b/src/WinSW.Tests/Util/CommandLineTestHelper.cs
@@ -24,16 +24,16 @@ $@"
C:\winsw\logs
";
- public static readonly ServiceDescriptor DefaultServiceDescriptor = ServiceDescriptor.FromXml(SeedXml);
+ public static readonly XmlServiceConfig DefaultServiceConfig = XmlServiceConfig.FromXml(SeedXml);
///
/// Runs a simle test, which returns the output CLI
///
/// CLI arguments to be passed
- /// Optional Service descriptor (will be used for initializationpurposes)
+ /// Optional Service config (will be used for initialization purposes)
/// STDOUT if there's no exceptions
/// Command failure
- public static string Test(string[] arguments, ServiceDescriptor descriptor = null)
+ public static string Test(string[] arguments, XmlServiceConfig config = null)
{
TextWriter tmpOut = Console.Out;
TextWriter tmpError = Console.Error;
@@ -43,7 +43,7 @@ $@"
Console.SetOut(swOut);
Console.SetError(swError);
- ServiceDescriptor.TestDescriptor = descriptor ?? DefaultServiceDescriptor;
+ XmlServiceConfig.TestConfig = config ?? DefaultServiceConfig;
try
{
_ = Program.Run(arguments);
@@ -52,7 +52,7 @@ $@"
{
Console.SetOut(tmpOut);
Console.SetError(tmpError);
- ServiceDescriptor.TestDescriptor = null;
+ XmlServiceConfig.TestConfig = null;
}
Assert.Equal(string.Empty, swError.ToString());
@@ -63,9 +63,9 @@ $@"
/// Runs a simle test, which returns the output CLI
///
/// CLI arguments to be passed
- /// Optional Service descriptor (will be used for initializationpurposes)
+ /// Optional Service config (will be used for initialization purposes)
/// Test results
- public static CommandLineTestResult ErrorTest(string[] arguments, ServiceDescriptor descriptor = null)
+ public static CommandLineTestResult ErrorTest(string[] arguments, XmlServiceConfig config = null)
{
Exception exception = null;
@@ -77,7 +77,7 @@ $@"
Console.SetOut(swOut);
Console.SetError(swError);
- ServiceDescriptor.TestDescriptor = descriptor ?? DefaultServiceDescriptor;
+ XmlServiceConfig.TestConfig = config ?? DefaultServiceConfig;
Program.TestExceptionHandler = (e, _) => exception = e;
try
{
@@ -91,7 +91,7 @@ $@"
{
Console.SetOut(tmpOut);
Console.SetError(tmpError);
- ServiceDescriptor.TestDescriptor = null;
+ XmlServiceConfig.TestConfig = null;
Program.TestExceptionHandler = null;
}
diff --git a/src/WinSW.Tests/Util/ConfigXmlBuilder.cs b/src/WinSW.Tests/Util/ConfigXmlBuilder.cs
index 48e4789..202758c 100644
--- a/src/WinSW.Tests/Util/ConfigXmlBuilder.cs
+++ b/src/WinSW.Tests/Util/ConfigXmlBuilder.cs
@@ -104,9 +104,9 @@ namespace WinSW.Tests.Util
return res;
}
- public ServiceDescriptor ToServiceDescriptor(bool dumpConfig = false)
+ public XmlServiceConfig ToServiceConfig(bool dumpConfig = false)
{
- return ServiceDescriptor.FromXml(this.ToXmlString(dumpConfig));
+ return XmlServiceConfig.FromXml(this.ToXmlString(dumpConfig));
}
public ConfigXmlBuilder WithRawEntry(string entry)
diff --git a/src/WinSW.Tests/Util/ServiceConfigAssert.cs b/src/WinSW.Tests/Util/ServiceConfigAssert.cs
new file mode 100644
index 0000000..dec9553
--- /dev/null
+++ b/src/WinSW.Tests/Util/ServiceConfigAssert.cs
@@ -0,0 +1,34 @@
+using System.Reflection;
+using WinSW.Configuration;
+using Xunit;
+
+namespace WinSW.Tests.Util
+{
+ public static class ServiceConfigAssert
+ {
+ public static void AssertAllOptionalPropertiesAreDefault(XmlServiceConfig config)
+ {
+ var testConfig = new TestServiceConfig(config);
+ foreach (var property in typeof(ServiceConfig).GetProperties())
+ {
+ if (property.GetMethod!.IsVirtual)
+ {
+ Assert.Equal(property.GetValue(testConfig, null), property.GetValue(config, null));
+ }
+ }
+ }
+
+ private sealed class TestServiceConfig : ServiceConfig
+ {
+ private readonly XmlServiceConfig config;
+
+ internal TestServiceConfig(XmlServiceConfig config) => this.config = config;
+
+ public override string FullPath => this.config.FullPath;
+
+ public override string Id => this.config.Id;
+
+ public override string Executable => this.config.Executable;
+ }
+ }
+}
diff --git a/src/WinSW.Tests/Util/ServiceDescriptorAssert.cs b/src/WinSW.Tests/Util/ServiceDescriptorAssert.cs
deleted file mode 100644
index b996074..0000000
--- a/src/WinSW.Tests/Util/ServiceDescriptorAssert.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using System.Collections.Generic;
-using System.Reflection;
-using WinSW.Configuration;
-using Xunit;
-
-namespace WinSW.Tests.Util
-{
- public static class ServiceDescriptorAssert
- {
- // TODO: convert to Extension attributes once the .NET dependency is upgraded
- // BTW there is a way to get them working in .NET2, but KISS
- public static void AssertPropertyIsDefault(ServiceDescriptor desc, string property)
- {
- PropertyInfo actualProperty = typeof(ServiceDescriptor).GetProperty(property);
- Assert.NotNull(actualProperty);
-
- PropertyInfo defaultProperty = typeof(DefaultWinSWSettings).GetProperty(property);
- Assert.NotNull(defaultProperty);
-
- Assert.Equal(defaultProperty.GetValue(ServiceDescriptor.Defaults, null), actualProperty.GetValue(desc, null));
- }
-
- public static void AssertPropertyIsDefault(ServiceDescriptor desc, List properties)
- {
- foreach (var prop in properties)
- {
- AssertPropertyIsDefault(desc, prop);
- }
- }
-
- public static void AssertAllOptionalPropertiesAreDefault(ServiceDescriptor desc)
- {
- AssertPropertyIsDefault(desc, AllOptionalProperties);
- }
-
- private static List AllProperties
- {
- get
- {
- var res = new List();
- var properties = typeof(IWinSWConfiguration).GetProperties();
- foreach (var prop in properties)
- {
- res.Add(prop.Name);
- }
-
- return res;
- }
- }
-
- private static List AllOptionalProperties
- {
- get
- {
- var properties = AllProperties;
- properties.Remove("FullPath");
- properties.Remove("Id");
- properties.Remove("Executable");
- properties.Remove("WorkingDirectory");
- return properties;
- }
- }
- }
-}
diff --git a/src/WinSW/Program.cs b/src/WinSW/Program.cs
index f7bb5e2..d988e13 100644
--- a/src/WinSW/Program.cs
+++ b/src/WinSW/Program.cs
@@ -71,20 +71,20 @@ namespace WinSW
{
Handler = CommandHandler.Create((string? pathToConfig) =>
{
- ServiceDescriptor descriptor;
+ XmlServiceConfig config;
try
{
- descriptor = ServiceDescriptor.Create(pathToConfig);
+ config = XmlServiceConfig.Create(pathToConfig);
}
catch (FileNotFoundException)
{
throw new CommandException("The specified command or file was not found.");
}
- InitLoggers(descriptor, enableConsoleLogging: false);
+ InitLoggers(config, enableConsoleLogging: false);
Log.Debug("Starting WinSW in service mode");
- ServiceBase.Run(new WrapperService(descriptor));
+ ServiceBase.Run(new WrapperService(config));
}),
};
@@ -320,8 +320,8 @@ namespace WinSW
void Install(string? pathToConfig, bool noElevate, string? username, string? password)
{
- ServiceDescriptor descriptor = ServiceDescriptor.Create(pathToConfig);
- InitLoggers(descriptor, enableConsoleLogging: true);
+ XmlServiceConfig config = XmlServiceConfig.Create(pathToConfig);
+ InitLoggers(config, enableConsoleLogging: true);
if (!elevated)
{
@@ -329,25 +329,25 @@ namespace WinSW
return;
}
- Log.Info("Installing the service with id '" + descriptor.Id + "'");
+ Log.Info("Installing the service with id '" + config.Id + "'");
using ServiceManager scm = ServiceManager.Open();
- if (scm.ServiceExists(descriptor.Id))
+ if (scm.ServiceExists(config.Id))
{
- Console.WriteLine("Service with id '" + descriptor.Id + "' already exists");
+ Console.WriteLine("Service with id '" + config.Id + "' already exists");
Console.WriteLine("To install the service, delete the existing one or change service Id in the configuration file");
- throw new CommandException("Installation failure: Service with id '" + descriptor.Id + "' already exists");
+ throw new CommandException("Installation failure: Service with id '" + config.Id + "' already exists");
}
- if (descriptor.HasServiceAccount())
+ if (config.HasServiceAccount())
{
- username = descriptor.ServiceAccountUserName ?? username;
- password = descriptor.ServiceAccountPassword ?? password;
+ username = config.ServiceAccountUserName ?? username;
+ password = config.ServiceAccountPassword ?? password;
if (username is null || password is null)
{
- switch (descriptor.ServiceAccountPrompt)
+ switch (config.ServiceAccountPrompt)
{
case "dialog":
Credentials.PropmtForCredentialsDialog(
@@ -370,45 +370,45 @@ namespace WinSW
}
using Service sc = scm.CreateService(
- descriptor.Id,
- descriptor.Caption,
- descriptor.StartMode,
- "\"" + descriptor.ExecutablePath + "\"" + (pathToConfig != null ? " \"" + Path.GetFullPath(pathToConfig) + "\"" : null),
- descriptor.ServiceDependencies,
+ config.Id,
+ config.Caption,
+ config.StartMode,
+ "\"" + config.ExecutablePath + "\"" + (pathToConfig != null ? " \"" + Path.GetFullPath(pathToConfig) + "\"" : null),
+ config.ServiceDependencies,
username,
password);
- string description = descriptor.Description;
+ string description = config.Description;
if (description.Length != 0)
{
sc.SetDescription(description);
}
- SC_ACTION[] actions = descriptor.FailureActions;
+ SC_ACTION[] actions = config.FailureActions;
if (actions.Length > 0)
{
- sc.SetFailureActions(descriptor.ResetFailureAfter, actions);
+ sc.SetFailureActions(config.ResetFailureAfter, actions);
}
- bool isDelayedAutoStart = descriptor.StartMode == ServiceStartMode.Automatic && descriptor.DelayedAutoStart;
+ bool isDelayedAutoStart = config.StartMode == ServiceStartMode.Automatic && config.DelayedAutoStart;
if (isDelayedAutoStart)
{
sc.SetDelayedAutoStart(true);
}
- if (descriptor.PreshutdownTimeout is TimeSpan preshutdownTimeout)
+ if (config.PreshutdownTimeout is TimeSpan preshutdownTimeout)
{
sc.SetPreshutdownTimeout(preshutdownTimeout);
}
- string? securityDescriptor = descriptor.SecurityDescriptor;
+ string? securityDescriptor = config.SecurityDescriptor;
if (securityDescriptor != null)
{
// throws ArgumentException
sc.SetSecurityDescriptor(new RawSecurityDescriptor(securityDescriptor));
}
- string eventLogSource = descriptor.Id;
+ string eventLogSource = config.Id;
if (!EventLog.SourceExists(eventLogSource))
{
EventLog.CreateEventSource(eventLogSource, "Application");
@@ -434,8 +434,8 @@ namespace WinSW
void Uninstall(string? pathToConfig, bool noElevate)
{
- ServiceDescriptor descriptor = ServiceDescriptor.Create(pathToConfig);
- InitLoggers(descriptor, enableConsoleLogging: true);
+ XmlServiceConfig config = XmlServiceConfig.Create(pathToConfig);
+ InitLoggers(config, enableConsoleLogging: true);
if (!elevated)
{
@@ -443,18 +443,18 @@ namespace WinSW
return;
}
- Log.Info("Uninstalling the service with id '" + descriptor.Id + "'");
+ Log.Info("Uninstalling the service with id '" + config.Id + "'");
using ServiceManager scm = ServiceManager.Open();
try
{
- using Service sc = scm.OpenService(descriptor.Id);
+ using Service sc = scm.OpenService(config.Id);
if (sc.Status == ServiceControllerStatus.Running)
{
// We could fail the opeartion here, but it would be an incompatible change.
// So it is just a warning
- Log.Warn("The service with id '" + descriptor.Id + "' is running. It may be impossible to uninstall it");
+ Log.Warn("The service with id '" + config.Id + "' is running. It may be impossible to uninstall it");
}
sc.Delete();
@@ -464,18 +464,18 @@ namespace WinSW
switch (inner.NativeErrorCode)
{
case Errors.ERROR_SERVICE_DOES_NOT_EXIST:
- Log.Warn("The service with id '" + descriptor.Id + "' does not exist. Nothing to uninstall");
+ Log.Warn("The service with id '" + config.Id + "' does not exist. Nothing to uninstall");
break; // there's no such service, so consider it already uninstalled
case Errors.ERROR_SERVICE_MARKED_FOR_DELETE:
- Log.Error("Failed to uninstall the service with id '" + descriptor.Id + "'"
+ Log.Error("Failed to uninstall the service with id '" + config.Id + "'"
+ ". It has been marked for deletion.");
// TODO: change the default behavior to Error?
break; // it's already uninstalled, so consider it a success
default:
- Log.Fatal("Failed to uninstall the service with id '" + descriptor.Id + "'. Error code is '" + inner.NativeErrorCode + "'");
+ Log.Fatal("Failed to uninstall the service with id '" + config.Id + "'. Error code is '" + inner.NativeErrorCode + "'");
throw;
}
}
@@ -483,8 +483,8 @@ namespace WinSW
void Start(string? pathToConfig, bool noElevate)
{
- ServiceDescriptor descriptor = ServiceDescriptor.Create(pathToConfig);
- InitLoggers(descriptor, enableConsoleLogging: true);
+ XmlServiceConfig config = XmlServiceConfig.Create(pathToConfig);
+ InitLoggers(config, enableConsoleLogging: true);
if (!elevated)
{
@@ -492,9 +492,9 @@ namespace WinSW
return;
}
- Log.Info("Starting the service with id '" + descriptor.Id + "'");
+ Log.Info("Starting the service with id '" + config.Id + "'");
- using var svc = new ServiceController(descriptor.Id);
+ using var svc = new ServiceController(config.Id);
try
{
@@ -508,14 +508,14 @@ namespace WinSW
catch (InvalidOperationException e)
when (e.InnerException is Win32Exception inner && inner.NativeErrorCode == Errors.ERROR_SERVICE_ALREADY_RUNNING)
{
- Log.Info($"The service with ID '{descriptor.Id}' has already been started");
+ Log.Info($"The service with ID '{config.Id}' has already been started");
}
}
void Stop(string? pathToConfig, bool noElevate, bool noWait, bool force)
{
- ServiceDescriptor descriptor = ServiceDescriptor.Create(pathToConfig);
- InitLoggers(descriptor, enableConsoleLogging: true);
+ XmlServiceConfig config = XmlServiceConfig.Create(pathToConfig);
+ InitLoggers(config, enableConsoleLogging: true);
if (!elevated)
{
@@ -523,9 +523,9 @@ namespace WinSW
return;
}
- Log.Info("Stopping the service with id '" + descriptor.Id + "'");
+ Log.Info("Stopping the service with id '" + config.Id + "'");
- using var svc = new ServiceController(descriptor.Id);
+ using var svc = new ServiceController(config.Id);
try
{
@@ -567,8 +567,8 @@ namespace WinSW
void Restart(string? pathToConfig, bool noElevate, bool force)
{
- ServiceDescriptor descriptor = ServiceDescriptor.Create(pathToConfig);
- InitLoggers(descriptor, enableConsoleLogging: true);
+ XmlServiceConfig config = XmlServiceConfig.Create(pathToConfig);
+ InitLoggers(config, enableConsoleLogging: true);
if (!elevated)
{
@@ -576,9 +576,9 @@ namespace WinSW
return;
}
- Log.Info("Restarting the service with id '" + descriptor.Id + "'");
+ Log.Info("Restarting the service with id '" + config.Id + "'");
- using var svc = new ServiceController(descriptor.Id);
+ using var svc = new ServiceController(config.Id);
List? startedDependentServices = null;
@@ -632,19 +632,19 @@ namespace WinSW
void RestartSelf(string? pathToConfig)
{
- ServiceDescriptor descriptor = ServiceDescriptor.Create(pathToConfig);
- InitLoggers(descriptor, enableConsoleLogging: true);
+ XmlServiceConfig config = XmlServiceConfig.Create(pathToConfig);
+ InitLoggers(config, enableConsoleLogging: true);
if (!elevated)
{
throw new CommandException(new Win32Exception(Errors.ERROR_ACCESS_DENIED));
}
- Log.Info("Restarting the service with id '" + descriptor.Id + "'");
+ Log.Info("Restarting the service with id '" + config.Id + "'");
// run restart from another process group. see README.md for why this is useful.
- if (!ProcessApis.CreateProcess(null, descriptor.ExecutablePath + " restart", IntPtr.Zero, IntPtr.Zero, false, ProcessApis.CREATE_NEW_PROCESS_GROUP, IntPtr.Zero, null, default, out _))
+ if (!ProcessApis.CreateProcess(null, config.ExecutablePath + " restart", IntPtr.Zero, IntPtr.Zero, false, ProcessApis.CREATE_NEW_PROCESS_GROUP, IntPtr.Zero, null, default, out _))
{
throw new CommandException("Failed to invoke restart: " + Marshal.GetLastWin32Error());
}
@@ -652,11 +652,11 @@ namespace WinSW
static void Status(string? pathToConfig)
{
- ServiceDescriptor descriptor = ServiceDescriptor.Create(pathToConfig);
- InitLoggers(descriptor, enableConsoleLogging: true);
+ XmlServiceConfig config = XmlServiceConfig.Create(pathToConfig);
+ InitLoggers(config, enableConsoleLogging: true);
- Log.Debug("User requested the status of the process with id '" + descriptor.Id + "'");
- using var svc = new ServiceController(descriptor.Id);
+ Log.Debug("User requested the status of the process with id '" + config.Id + "'");
+ using var svc = new ServiceController(config.Id);
try
{
Console.WriteLine(svc.Status == ServiceControllerStatus.Running ? "Started" : "Stopped");
@@ -670,8 +670,8 @@ namespace WinSW
void Test(string? pathToConfig, bool noElevate, int? timeout, bool noBreak)
{
- ServiceDescriptor descriptor = ServiceDescriptor.Create(pathToConfig);
- InitLoggers(descriptor, enableConsoleLogging: true);
+ XmlServiceConfig config = XmlServiceConfig.Create(pathToConfig);
+ InitLoggers(config, enableConsoleLogging: true);
if (!elevated)
{
@@ -679,7 +679,7 @@ namespace WinSW
return;
}
- using WrapperService wsvc = new WrapperService(descriptor);
+ using WrapperService wsvc = new WrapperService(config);
wsvc.RaiseOnStart(args);
try
{
@@ -715,8 +715,8 @@ namespace WinSW
void Refresh(string? pathToConfig, bool noElevate)
{
- ServiceDescriptor descriptor = ServiceDescriptor.Create(pathToConfig);
- InitLoggers(descriptor, enableConsoleLogging: true);
+ XmlServiceConfig config = XmlServiceConfig.Create(pathToConfig);
+ InitLoggers(config, enableConsoleLogging: true);
if (!elevated)
{
@@ -727,30 +727,30 @@ namespace WinSW
using ServiceManager scm = ServiceManager.Open();
try
{
- using Service sc = scm.OpenService(descriptor.Id);
+ using Service sc = scm.OpenService(config.Id);
- sc.ChangeConfig(descriptor.Caption, descriptor.StartMode, descriptor.ServiceDependencies);
+ sc.ChangeConfig(config.Caption, config.StartMode, config.ServiceDependencies);
- sc.SetDescription(descriptor.Description);
+ sc.SetDescription(config.Description);
- SC_ACTION[] actions = descriptor.FailureActions;
+ SC_ACTION[] actions = config.FailureActions;
if (actions.Length > 0)
{
- sc.SetFailureActions(descriptor.ResetFailureAfter, actions);
+ sc.SetFailureActions(config.ResetFailureAfter, actions);
}
- bool isDelayedAutoStart = descriptor.StartMode == ServiceStartMode.Automatic && descriptor.DelayedAutoStart;
+ bool isDelayedAutoStart = config.StartMode == ServiceStartMode.Automatic && config.DelayedAutoStart;
if (isDelayedAutoStart)
{
sc.SetDelayedAutoStart(true);
}
- if (descriptor.PreshutdownTimeout is TimeSpan preshutdownTimeout)
+ if (config.PreshutdownTimeout is TimeSpan preshutdownTimeout)
{
sc.SetPreshutdownTimeout(preshutdownTimeout);
}
- string? securityDescriptor = descriptor.SecurityDescriptor;
+ string? securityDescriptor = config.SecurityDescriptor;
if (securityDescriptor != null)
{
// throws ArgumentException
@@ -807,9 +807,9 @@ namespace WinSW
[MethodImpl(MethodImplOptions.NoInlining)]
private static void ThrowNoSuchService(Win32Exception inner) => throw new CommandException(inner);
- private static void InitLoggers(ServiceDescriptor descriptor, bool enableConsoleLogging)
+ private static void InitLoggers(XmlServiceConfig config, bool enableConsoleLogging)
{
- if (ServiceDescriptor.TestDescriptor != null)
+ if (XmlServiceConfig.TestConfig != null)
{
return;
}
@@ -828,7 +828,7 @@ namespace WinSW
List appenders = new List();
// .wrapper.log
- string wrapperLogPath = Path.Combine(descriptor.LogDirectory, descriptor.BaseName + ".wrapper.log");
+ string wrapperLogPath = Path.Combine(config.LogDirectory, config.BaseName + ".wrapper.log");
var wrapperLog = new FileAppender
{
AppendToFile = true,
diff --git a/src/WinSW/WrapperService.cs b/src/WinSW/WrapperService.cs
index be11800..8594736 100644
--- a/src/WinSW/WrapperService.cs
+++ b/src/WinSW/WrapperService.cs
@@ -17,7 +17,7 @@ namespace WinSW
public sealed class WrapperService : ServiceBase, IEventLogger, IServiceEventLog
{
private readonly Process process = new Process();
- private readonly ServiceDescriptor descriptor;
+ private readonly XmlServiceConfig config;
private Dictionary? envs;
internal WinSWExtensionManager ExtensionManager { get; }
@@ -45,11 +45,11 @@ namespace WinSW
///
public static Version Version => Assembly.GetExecutingAssembly().GetName().Version!;
- public WrapperService(ServiceDescriptor descriptor)
+ public WrapperService(XmlServiceConfig config)
{
- this.descriptor = descriptor;
- this.ServiceName = this.descriptor.Id;
- this.ExtensionManager = new WinSWExtensionManager(this.descriptor);
+ this.config = config;
+ this.ServiceName = config.Id;
+ this.ExtensionManager = new WinSWExtensionManager(config);
this.CanShutdown = true;
this.CanStop = true;
this.CanPauseAndContinue = false;
@@ -59,12 +59,12 @@ namespace WinSW
// Register the event log provider
eventLogProvider.Service = this;
- if (descriptor.Preshutdown)
+ if (config.Preshutdown)
{
this.AcceptPreshutdown();
}
- Environment.CurrentDirectory = descriptor.WorkingDirectory;
+ Environment.CurrentDirectory = config.WorkingDirectory;
}
///
@@ -73,7 +73,7 @@ namespace WinSW
///
private void HandleFileCopies()
{
- var file = this.descriptor.BasePath + ".copies";
+ var file = this.config.BasePath + ".copies";
if (!File.Exists(file))
{
return; // nothing to handle
@@ -123,14 +123,14 @@ namespace WinSW
/// Log Handler, which should be used for the spawned process
private LogHandler CreateExecutableLogHandler()
{
- string logDirectory = this.descriptor.LogDirectory;
+ string logDirectory = this.config.LogDirectory;
if (!Directory.Exists(logDirectory))
{
Directory.CreateDirectory(logDirectory);
}
- LogHandler logAppender = this.descriptor.LogHandler;
+ LogHandler logAppender = this.config.LogHandler;
logAppender.EventLogger = this;
return logAppender;
}
@@ -243,12 +243,12 @@ namespace WinSW
private void DoStart()
{
- this.envs = this.descriptor.EnvironmentVariables;
+ this.envs = this.config.EnvironmentVariables;
this.HandleFileCopies();
// handle downloads
- List downloads = this.descriptor.Downloads;
+ List downloads = this.config.Downloads;
Task[] tasks = new Task[downloads.Count];
for (int i = 0; i < downloads.Count; i++)
{
@@ -287,10 +287,10 @@ namespace WinSW
try
{
- string? prestartExecutable = this.descriptor.PrestartExecutable;
+ string? prestartExecutable = this.config.PrestartExecutable;
if (prestartExecutable != null)
{
- using Process process = this.StartProcess(prestartExecutable, this.descriptor.PrestartArguments);
+ using Process process = this.StartProcess(prestartExecutable, this.config.PrestartArguments);
this.WaitForProcessToExit(process);
this.LogInfo($"Pre-start process '{process.Format()}' exited with code {process.ExitCode}.");
}
@@ -300,24 +300,24 @@ namespace WinSW
Log.Error(e);
}
- string startArguments = this.descriptor.StartArguments ?? this.descriptor.Arguments;
+ string startArguments = this.config.StartArguments ?? this.config.Arguments;
- this.LogInfo("Starting " + this.descriptor.Executable);
+ this.LogInfo("Starting " + this.config.Executable);
// Load and start extensions
this.ExtensionManager.LoadExtensions();
this.ExtensionManager.FireOnWrapperStarted();
LogHandler executableLogHandler = this.CreateExecutableLogHandler();
- this.StartProcess(this.process, startArguments, this.descriptor.Executable, executableLogHandler);
+ this.StartProcess(this.process, startArguments, this.config.Executable, executableLogHandler);
this.ExtensionManager.FireOnProcessStarted(this.process);
try
{
- string? poststartExecutable = this.descriptor.PoststartExecutable;
+ string? poststartExecutable = this.config.PoststartExecutable;
if (poststartExecutable != null)
{
- using Process process = this.StartProcess(poststartExecutable, this.descriptor.PoststartArguments, process =>
+ using Process process = this.StartProcess(poststartExecutable, this.config.PoststartArguments, process =>
{
this.LogInfo($"Post-start process '{process.Format()}' exited with code {process.ExitCode}.");
});
@@ -336,10 +336,10 @@ namespace WinSW
{
try
{
- string? prestopExecutable = this.descriptor.PrestopExecutable;
+ string? prestopExecutable = this.config.PrestopExecutable;
if (prestopExecutable != null)
{
- using Process process = this.StartProcess(prestopExecutable, this.descriptor.PrestopArguments);
+ using Process process = this.StartProcess(prestopExecutable, this.config.PrestopArguments);
this.WaitForProcessToExit(process);
this.LogInfo($"Pre-stop process '{process.Format()}' exited with code {process.ExitCode}.");
}
@@ -349,15 +349,15 @@ namespace WinSW
Log.Error(e);
}
- string? stopArguments = this.descriptor.StopArguments;
- this.LogInfo("Stopping " + this.descriptor.Id);
+ string? stopArguments = this.config.StopArguments;
+ this.LogInfo("Stopping " + this.config.Id);
this.orderlyShutdown = true;
this.process.EnableRaisingEvents = false;
if (stopArguments is null)
{
Log.Debug("ProcessKill " + this.process.Id);
- ProcessHelper.StopProcessTree(this.process, this.descriptor.StopTimeout);
+ ProcessHelper.StopProcessTree(this.process, this.config.StopTimeout);
this.ExtensionManager.FireOnProcessTerminated(this.process);
}
else
@@ -366,7 +366,7 @@ namespace WinSW
Process stopProcess = new Process();
- string stopExecutable = this.descriptor.StopExecutable ?? this.descriptor.Executable;
+ string stopExecutable = this.config.StopExecutable ?? this.config.Executable;
// TODO: Redirect logging to Log4Net once https://github.com/kohsuke/winsw/pull/213 is integrated
this.StartProcess(stopProcess, stopArguments, stopExecutable, null);
@@ -378,10 +378,10 @@ namespace WinSW
try
{
- string? poststopExecutable = this.descriptor.PoststopExecutable;
+ string? poststopExecutable = this.config.PoststopExecutable;
if (poststopExecutable != null)
{
- using Process process = this.StartProcess(poststopExecutable, this.descriptor.PoststopArguments);
+ using Process process = this.StartProcess(poststopExecutable, this.config.PoststopArguments);
this.WaitForProcessToExit(process);
this.LogInfo($"Post-stop process '{process.Format()}' exited with code {process.ExitCode}.");
}
@@ -394,12 +394,12 @@ namespace WinSW
// Stop extensions
this.ExtensionManager.FireBeforeWrapperStopped();
- if (this.shuttingdown && this.descriptor.BeepOnShutdown)
+ if (this.shuttingdown && this.config.BeepOnShutdown)
{
Console.Beep();
}
- Log.Info("Finished " + this.descriptor.Id);
+ Log.Info("Finished " + this.config.Id);
}
private void WaitForProcessToExit(Process process)
@@ -485,11 +485,11 @@ namespace WinSW
executable: executable,
arguments: arguments,
envVars: this.envs,
- workingDirectory: this.descriptor.WorkingDirectory,
- priority: this.descriptor.Priority,
+ workingDirectory: this.config.WorkingDirectory,
+ priority: this.config.Priority,
onExited: OnProcessCompleted,
logHandler: logHandler,
- hideWindow: this.descriptor.HideWindow);
+ hideWindow: this.config.HideWindow);
}
private Process StartProcess(string executable, string? arguments, Action? onExited = null)
@@ -497,7 +497,7 @@ namespace WinSW
var info = new ProcessStartInfo(executable, arguments)
{
UseShellExecute = false,
- WorkingDirectory = this.descriptor.WorkingDirectory,
+ WorkingDirectory = this.config.WorkingDirectory,
};
Process process = Process.Start(info);