Environment variable expansion in extensions (#677)

pull/678/head
Buddhika Chathuranga 2020-12-28 17:46:03 +05:30 committed by GitHub
parent 2c86e14dec
commit 027a8d30e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 330 additions and 347 deletions

View File

@ -10,7 +10,7 @@ namespace WinSW.Configuration
/// <summary>
/// Default WinSW settings.
/// </summary>
public sealed class DefaultWinSWSettings : IWinSWConfiguration
public sealed class DefaultSettings : IServiceConfig
{
public static LogDefaults DefaultLogSettings { get; } = new LogDefaults();
@ -86,11 +86,11 @@ namespace WinSW.Configuration
public class LogDefaults : Log
{
private readonly DefaultWinSWSettings defaults;
private readonly DefaultSettings defaults;
public LogDefaults()
{
this.defaults = new DefaultWinSWSettings();
this.defaults = new DefaultSettings();
}
public override string Mode => "append";
@ -133,32 +133,13 @@ namespace WinSW.Configuration
public bool BeepOnShutdown => false;
// Extensions
public XmlNode? ExtensionsConfiguration => null;
public XmlNode? XmlExtensions => null;
public List<YamlExtensionConfiguration>? YamlExtensionsConfiguration => new(0);
public List<YamlExtensionConfig>? YamlExtensions => new(0);
public string BaseName
{
get
{
string baseName = Path.GetFileNameWithoutExtension(this.ExecutablePath);
if (baseName.EndsWith(".vshost"))
{
baseName = baseName.Substring(0, baseName.Length - 7);
}
public string BaseName => Path.GetFileNameWithoutExtension(this.ExecutablePath);
return baseName;
}
}
public string BasePath
{
get
{
var d = new DirectoryInfo(Path.GetDirectoryName(this.ExecutablePath)!);
return Path.Combine(d.FullName, this.BaseName);
}
}
public string BasePath => Path.Combine(Path.GetDirectoryName(this.ExecutablePath)!, this.BaseName);
public List<string> ExtensionIds => new(0);

View File

@ -6,7 +6,7 @@ using System.Xml;
namespace WinSW.Configuration
{
public interface IWinSWConfiguration
public interface IServiceConfig
{
// TODO: Document the parameters && refactor
string Name { get; }
@ -74,9 +74,9 @@ namespace WinSW.Configuration
bool BeepOnShutdown { get; }
// Extensions
XmlNode? ExtensionsConfiguration { get; }
XmlNode? XmlExtensions { get; }
List<YamlExtensionConfiguration>? YamlExtensionsConfiguration { get; }
List<YamlExtensionConfig>? YamlExtensions { get; }
List<string> ExtensionIds { get; }

View File

@ -1,4 +1,4 @@
using YamlDotNet.Serialization;
using YamlDotNet.Serialization;
namespace WinSW.Configuration
{

View File

@ -14,13 +14,13 @@ namespace WinSW
/// <summary>
/// In-memory representation of the configuration file.
/// </summary>
public class ServiceDescriptor : IWinSWConfiguration
public class XmlServiceConfig : IServiceConfig
{
protected readonly XmlDocument dom = new();
private readonly Dictionary<string, string> environmentVariables;
public static DefaultWinSWSettings Defaults { get; } = new DefaultWinSWSettings();
public static DefaultSettings Defaults { get; } = new DefaultSettings();
/// <summary>
/// Where did we find the configuration file?
@ -39,7 +39,7 @@ namespace WinSW
// Currently there is no opportunity to alter the executable path
public virtual string ExecutablePath => Defaults.ExecutablePath;
public ServiceDescriptor(string baseName, string directory)
public XmlServiceConfig(string baseName, string directory)
{
this.BaseName = baseName;
this.BasePath = Path.Combine(directory, this.BaseName);
@ -72,7 +72,7 @@ namespace WinSW
/// Loads descriptor from existing DOM
/// </summary>
#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;
@ -80,11 +80,11 @@ namespace WinSW
this.environmentVariables = this.LoadEnvironmentVariables();
}
public static ServiceDescriptor FromXML(string xml)
public static XmlServiceConfig FromXML(string xml)
{
var xmlDom = new XmlDocument();
xmlDom.LoadXml(xml);
return new ServiceDescriptor(xmlDom);
return new XmlServiceConfig(xmlDom);
}
private string SingleElement(string tagName)
@ -208,7 +208,7 @@ namespace WinSW
{
get
{
var argumentNode = this.ExtensionsConfiguration;
var argumentNode = this.XmlExtensions;
var extensions = argumentNode?.SelectNodes("extension");
if (extensions is null)
{
@ -225,7 +225,7 @@ namespace WinSW
}
}
public XmlNode? ExtensionsConfiguration => this.dom.SelectSingleNode("//extensions");
public XmlNode? XmlExtensions => this.dom.SelectSingleNode("//extensions");
/// <summary>
/// Combines the contents of all the elements of the given name,
@ -314,34 +314,34 @@ namespace WinSW
private class XmlLogSettings : Log
{
private readonly ServiceDescriptor d;
private readonly XmlServiceConfig config;
public XmlLogSettings(ServiceDescriptor d)
public XmlLogSettings(XmlServiceConfig config)
{
this.d = d;
this.config = config;
}
private XmlElement E
private XmlElement Element
{
get
{
var e = (XmlElement?)this.d.dom.SelectSingleNode("//logmode");
var element = (XmlElement?)this.config.dom.SelectSingleNode("//logmode");
// this is more modern way, to support nested elements as configuration
e ??= (XmlElement?)this.d.dom.SelectSingleNode("//log")!; // WARNING: NRE
return e;
element ??= (XmlElement?)this.config.dom.SelectSingleNode("//log")!; // WARNING: NRE
return element;
}
}
public override string? Mode => this.d.LogMode;
public override string? Mode => this.config.LogMode;
public override string Name => this.d.LogName;
public override string Name => this.config.LogName;
public override string Directory
{
get
{
var loggingNode = this.d.dom.SelectSingleNode("//logpath");
var loggingNode = this.config.dom.SelectSingleNode("//logpath");
return loggingNode is null
? Defaults.LogDirectory
@ -349,17 +349,17 @@ namespace WinSW
}
}
public override int? SizeThreshold => this.d.SingleIntElement(this.E, "sizeThreshold", 10 * 1024);
public override int? SizeThreshold => this.config.SingleIntElement(this.Element, "sizeThreshold", 10 * 1024);
public override int? KeepFiles => this.d.SingleIntElement(this.E, "keepFiles", SizeBasedRollingLogAppender.DefaultFilesToKeep);
public override int? KeepFiles => this.config.SingleIntElement(this.Element, "keepFiles", SizeBasedRollingLogAppender.DefaultFilesToKeep);
public override int? Period => this.d.SingleIntElement(this.E, "period", 1);
public override int? Period => this.config.SingleIntElement(this.Element, "period", 1);
public override string Pattern
{
get
{
var patternNode = this.E.SelectSingleNode("pattern");
var patternNode = this.Element.SelectSingleNode("pattern");
if (patternNode is null)
{
throw new InvalidDataException("Time Based rolling policy is specified but no pattern can be found in configuration XML.");
@ -369,15 +369,15 @@ namespace WinSW
}
}
public override bool OutFileDisabled => this.d.SingleBoolElement("outfiledisabled", Defaults.OutFileDisabled);
public override bool OutFileDisabled => this.config.SingleBoolElement("outfiledisabled", Defaults.OutFileDisabled);
public override bool ErrFileDisabled => this.d.SingleBoolElement("errfiledisabled", Defaults.ErrFileDisabled);
public override bool ErrFileDisabled => this.config.SingleBoolElement("errfiledisabled", Defaults.ErrFileDisabled);
public override string OutFilePattern
{
get
{
var loggingName = this.d.dom.SelectSingleNode("//outfilepattern");
var loggingName = this.config.dom.SelectSingleNode("//outfilepattern");
return loggingName is null ? Defaults.OutFilePattern : Environment.ExpandEnvironmentVariables(loggingName.InnerText);
}
@ -387,7 +387,7 @@ namespace WinSW
{
get
{
var loggingName = this.d.dom.SelectSingleNode("//errfilepattern");
var loggingName = this.config.dom.SelectSingleNode("//errfilepattern");
return loggingName is null ? Defaults.ErrFilePattern : Environment.ExpandEnvironmentVariables(loggingName.InnerText);
}
@ -397,7 +397,7 @@ namespace WinSW
{
get
{
var autoRollAtTimeNode = this.E.SelectSingleNode("autoRollAtTime");
var autoRollAtTimeNode = this.Element.SelectSingleNode("autoRollAtTime");
return autoRollAtTimeNode?.InnerText;
}
}
@ -406,7 +406,7 @@ namespace WinSW
{
get
{
var zipolderthannumdaysNode = this.E.SelectSingleNode("zipOlderThanNumDays");
var zipolderthannumdaysNode = this.Element.SelectSingleNode("zipOlderThanNumDays");
int? zipolderthannumdays = null;
if (zipolderthannumdaysNode != null)
{
@ -427,7 +427,7 @@ namespace WinSW
{
get
{
var zipdateformatNode = this.E.SelectSingleNode("zipDateFormat");
var zipdateformatNode = this.Element.SelectSingleNode("zipDateFormat");
return zipdateformatNode is null ? null : zipdateformatNode.InnerText;
}
}
@ -690,6 +690,6 @@ namespace WinSW
return environment;
}
public List<YamlExtensionConfiguration>? YamlExtensionsConfiguration => Defaults.YamlExtensionsConfiguration;
public List<YamlExtensionConfig>? YamlExtensions => Defaults.YamlExtensions;
}
}

View File

@ -1,10 +1,10 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using YamlDotNet.Serialization;
namespace WinSW.Configuration
{
public class YamlExtensionConfiguration
public class YamlExtensionConfig
{
[YamlMember(Alias = "id")]
public string? ExtensionId { get; set; }

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@ -7,19 +7,20 @@ using System.Xml;
using WinSW.Native;
using WinSW.Util;
using YamlDotNet.Serialization;
using static System.Environment;
using static WinSW.Download;
namespace WinSW.Configuration
{
public class YamlConfiguration : IWinSWConfiguration
public class YamlServiceConfig : IServiceConfig
{
public readonly DefaultWinSWSettings Defaults;
private readonly DefaultSettings defaults;
public YamlConfiguration()
public YamlServiceConfig()
{
this.Defaults = new DefaultWinSWSettings();
this.BaseName = this.Defaults.BaseName;
this.BasePath = this.Defaults.BasePath;
this.defaults = new DefaultSettings();
this.BaseName = this.defaults.BaseName;
this.BasePath = this.defaults.BasePath;
}
[YamlMember(Alias = "id")]
@ -117,11 +118,11 @@ namespace WinSW.Configuration
public class YamlLog : Log
{
private readonly YamlConfiguration configs;
private readonly YamlServiceConfig configs;
public YamlLog()
{
this.configs = new YamlConfiguration();
this.configs = new YamlServiceConfig();
}
[YamlMember(Alias = "mode")]
@ -169,7 +170,7 @@ namespace WinSW.Configuration
public string? ZipDateFormatYamlLog { get; set; }
public override string Mode => this.ModeYamlLog is null ?
DefaultWinSWSettings.DefaultLogSettings.Mode :
DefaultSettings.DefaultLogSettings.Mode :
this.ModeYamlLog;
public override string Name
@ -177,8 +178,8 @@ namespace WinSW.Configuration
get
{
return this.NameYamlLog is null ?
DefaultWinSWSettings.DefaultLogSettings.Name :
ExpandEnv(this.NameYamlLog);
DefaultSettings.DefaultLogSettings.Name :
ExpandEnvironmentVariables(this.NameYamlLog);
}
}
@ -187,8 +188,8 @@ namespace WinSW.Configuration
get
{
return this.LogPathYamlLog is null ?
DefaultWinSWSettings.DefaultLogSettings.Directory :
ExpandEnv(this.LogPathYamlLog);
DefaultSettings.DefaultLogSettings.Directory :
ExpandEnvironmentVariables(this.LogPathYamlLog);
}
}
@ -197,7 +198,7 @@ namespace WinSW.Configuration
get
{
return this.SizeThresholdYamlLog is null ?
DefaultWinSWSettings.DefaultLogSettings.SizeThreshold :
DefaultSettings.DefaultLogSettings.SizeThreshold :
this.SizeThresholdYamlLog;
}
}
@ -207,7 +208,7 @@ namespace WinSW.Configuration
get
{
return this.KeepFilesYamlLog is null ?
DefaultWinSWSettings.DefaultLogSettings.KeepFiles :
DefaultSettings.DefaultLogSettings.KeepFiles :
this.KeepFilesYamlLog;
}
}
@ -221,7 +222,7 @@ namespace WinSW.Configuration
return this.PatternYamlLog;
}
return DefaultWinSWSettings.DefaultLogSettings.Pattern;
return DefaultSettings.DefaultLogSettings.Pattern;
}
}
@ -232,7 +233,7 @@ namespace WinSW.Configuration
get
{
return this.OutFileDisabledYamlLog is null ?
DefaultWinSWSettings.DefaultLogSettings.OutFileDisabled :
DefaultSettings.DefaultLogSettings.OutFileDisabled :
(bool)this.OutFileDisabledYamlLog;
}
}
@ -242,7 +243,7 @@ namespace WinSW.Configuration
get
{
return this.ErrFileDisabledYamlLog is null ?
this.configs.Defaults.ErrFileDisabled :
this.configs.defaults.ErrFileDisabled :
(bool)this.ErrFileDisabledYamlLog;
}
}
@ -252,8 +253,8 @@ namespace WinSW.Configuration
get
{
return this.OutFilePatternYamlLog is null ?
DefaultWinSWSettings.DefaultLogSettings.OutFilePattern :
ExpandEnv(this.OutFilePatternYamlLog);
DefaultSettings.DefaultLogSettings.OutFilePattern :
ExpandEnvironmentVariables(this.OutFilePatternYamlLog);
}
}
@ -262,8 +263,8 @@ namespace WinSW.Configuration
get
{
return this.ErrFilePatternYamlLog is null ?
DefaultWinSWSettings.DefaultLogSettings.ErrFilePattern :
ExpandEnv(this.ErrFilePatternYamlLog);
DefaultSettings.DefaultLogSettings.ErrFilePattern :
ExpandEnvironmentVariables(this.ErrFilePatternYamlLog);
}
}
@ -272,7 +273,7 @@ namespace WinSW.Configuration
get
{
return this.AutoRollAtTimeYamlLog is null ?
DefaultWinSWSettings.DefaultLogSettings.AutoRollAtTime :
DefaultSettings.DefaultLogSettings.AutoRollAtTime :
this.AutoRollAtTimeYamlLog;
}
}
@ -302,7 +303,7 @@ namespace WinSW.Configuration
get
{
return this.ZipDateFormatYamlLog is null ?
DefaultWinSWSettings.DefaultLogSettings.ZipDateFormat :
DefaultSettings.DefaultLogSettings.ZipDateFormat :
this.ZipDateFormatYamlLog;
}
}
@ -334,15 +335,15 @@ namespace WinSW.Configuration
[YamlMember(Alias = "proxy")]
public string? ProxyYamlDownload { get; set; }
public string FromDownload => ExpandEnv(this.FromYamlDownload);
public string FromDownload => ExpandEnvironmentVariables(this.FromYamlDownload);
public string ToDownload => ExpandEnv(this.ToYamlDownload);
public string ToDownload => ExpandEnvironmentVariables(this.ToYamlDownload);
public string? UsernameDownload => this.UsernameYamlDownload is null ? null : ExpandEnv(this.UsernameYamlDownload);
public string? UsernameDownload => this.UsernameYamlDownload is null ? null : ExpandEnvironmentVariables(this.UsernameYamlDownload);
public string? PasswordDownload => this.PasswordYamlDownload is null ? null : ExpandEnv(this.PasswordYamlDownload);
public string? PasswordDownload => this.PasswordYamlDownload is null ? null : ExpandEnvironmentVariables(this.PasswordYamlDownload);
public string? ProxyDownload => this.ProxyYamlDownload is null ? null : ExpandEnv(this.ProxyYamlDownload);
public string? ProxyDownload => this.ProxyYamlDownload is null ? null : ExpandEnvironmentVariables(this.ProxyYamlDownload);
public AuthType AuthDownload
{
@ -353,7 +354,7 @@ namespace WinSW.Configuration
return AuthType.None;
}
string auth = ExpandEnv(this.AuthYamlDownload);
string auth = ExpandEnvironmentVariables(this.AuthYamlDownload);
try
{
@ -407,17 +408,17 @@ namespace WinSW.Configuration
switch (type)
{
case ArgType.Arg:
return this.Defaults.Arguments;
return this.defaults.Arguments;
case ArgType.Startarg:
return this.Defaults.StartArguments;
return this.defaults.StartArguments;
case ArgType.Stoparg:
return this.Defaults.StopArguments;
return this.defaults.StopArguments;
default:
return string.Empty;
}
}
return ExpandEnv(args);
return ExpandEnvironmentVariables(args);
}
private enum ArgType
@ -431,7 +432,7 @@ namespace WinSW.Configuration
{
if (downloads is null)
{
return this.Defaults.Downloads;
return this.defaults.Downloads;
}
var result = new List<Download>(downloads.Count);
@ -452,31 +453,26 @@ namespace WinSW.Configuration
return result;
}
internal static string ExpandEnv(string str)
{
return Environment.ExpandEnvironmentVariables(str);
}
public string Name => this.IdYaml is null ? this.defaults.Name : ExpandEnvironmentVariables(this.IdYaml);
public string Name => this.IdYaml is null ? this.Defaults.Name : ExpandEnv(this.IdYaml);
public string Description => this.DescriptionYaml is null ? this.defaults.Description : ExpandEnvironmentVariables(this.DescriptionYaml);
public string Description => this.DescriptionYaml is null ? this.Defaults.Description : ExpandEnv(this.DescriptionYaml);
public string Executable => this.ExecutableYaml is null ? this.Defaults.Executable : ExpandEnv(this.ExecutableYaml);
public string Executable => this.ExecutableYaml is null ? this.defaults.Executable : ExpandEnvironmentVariables(this.ExecutableYaml);
public string ExecutablePath => this.ExecutablePathYaml is null ?
this.Defaults.ExecutablePath :
ExpandEnv(this.ExecutablePathYaml);
this.defaults.ExecutablePath :
ExpandEnvironmentVariables(this.ExecutablePathYaml);
public string DisplayName => this.NameYaml is null ? this.Defaults.DisplayName : ExpandEnv(this.NameYaml);
public string DisplayName => this.NameYaml is null ? this.defaults.DisplayName : ExpandEnvironmentVariables(this.NameYaml);
public bool HideWindow => this.HideWindowYaml is null ? this.Defaults.HideWindow : (bool)this.HideWindowYaml;
public bool HideWindow => this.HideWindowYaml is null ? this.defaults.HideWindow : (bool)this.HideWindowYaml;
public bool StopParentProcessFirst
{
get
{
return this.StopParentProcessFirstYaml is null ?
this.Defaults.StopParentProcessFirst :
this.defaults.StopParentProcessFirst :
(bool)this.StopParentProcessFirstYaml;
}
}
@ -487,10 +483,10 @@ namespace WinSW.Configuration
{
if (this.StartModeYaml is null)
{
return this.Defaults.StartMode;
return this.defaults.StartMode;
}
string p = ExpandEnv(this.StartModeYaml);
string p = ExpandEnvironmentVariables(this.StartModeYaml);
try
{
@ -514,7 +510,7 @@ namespace WinSW.Configuration
get
{
string? args = this.GetArguments(this.ArgumentsYaml, ArgType.Arg);
return args is null ? this.Defaults.Arguments : args;
return args is null ? this.defaults.Arguments : args;
}
}
@ -527,8 +523,8 @@ namespace WinSW.Configuration
get
{
return this.StopExecutableYaml is null ?
this.Defaults.StopExecutable :
ExpandEnv(this.StopExecutableYaml);
this.defaults.StopExecutable :
ExpandEnvironmentVariables(this.StopExecutableYaml);
}
}
@ -553,12 +549,12 @@ namespace WinSW.Configuration
}
public TimeSpan ResetFailureAfter => this.ResetFailureAfterYaml is null ?
this.Defaults.ResetFailureAfter :
this.defaults.ResetFailureAfter :
ConfigHelper.ParseTimeSpan(this.ResetFailureAfterYaml);
public string WorkingDirectory => this.WorkingDirectoryYaml is null ?
this.Defaults.WorkingDirectory :
ExpandEnv(this.WorkingDirectoryYaml);
this.defaults.WorkingDirectory :
ExpandEnvironmentVariables(this.WorkingDirectoryYaml);
public ProcessPriorityClass Priority
{
@ -566,10 +562,10 @@ namespace WinSW.Configuration
{
if (this.PriorityYaml is null)
{
return this.Defaults.Priority;
return this.defaults.Priority;
}
string p = ExpandEnv(this.PriorityYaml);
string p = ExpandEnvironmentVariables(this.PriorityYaml);
try
{
@ -588,7 +584,7 @@ namespace WinSW.Configuration
}
}
public TimeSpan StopTimeout => this.StopTimeoutYaml is null ? this.Defaults.StopTimeout : ConfigHelper.ParseTimeSpan(this.StopTimeoutYaml);
public TimeSpan StopTimeout => this.StopTimeoutYaml is null ? this.defaults.StopTimeout : ConfigHelper.ParseTimeSpan(this.StopTimeoutYaml);
public string[] ServiceDependencies
{
@ -596,25 +592,25 @@ namespace WinSW.Configuration
{
if (this.ServiceDependenciesYaml is null)
{
return this.Defaults.ServiceDependencies;
return this.defaults.ServiceDependencies;
}
var result = new List<string>(0);
foreach (string item in this.ServiceDependenciesYaml)
{
result.Add(ExpandEnv(item));
result.Add(ExpandEnvironmentVariables(item));
}
return result.ToArray();
}
}
public TimeSpan WaitHint => this.WaitHintYaml is null ? this.Defaults.WaitHint : ConfigHelper.ParseTimeSpan(this.WaitHintYaml);
public TimeSpan WaitHint => this.WaitHintYaml is null ? this.defaults.WaitHint : ConfigHelper.ParseTimeSpan(this.WaitHintYaml);
public TimeSpan SleepTime => this.SleepTimeYaml is null ? this.Defaults.SleepTime : ConfigHelper.ParseTimeSpan(this.SleepTimeYaml);
public TimeSpan SleepTime => this.SleepTimeYaml is null ? this.defaults.SleepTime : ConfigHelper.ParseTimeSpan(this.SleepTimeYaml);
public bool Interactive => this.InteractiveYaml is null ? this.Defaults.Interactive : (bool)this.InteractiveYaml;
public bool Interactive => this.InteractiveYaml is null ? this.defaults.Interactive : (bool)this.InteractiveYaml;
public List<Download> Downloads => this.GetDownloads(this.DownloadsYaml);
@ -624,7 +620,7 @@ namespace WinSW.Configuration
{
if (this.EnvironmentVariablesYaml is null)
{
this.EnvironmentVariables = this.Defaults.EnvironmentVariables;
this.EnvironmentVariables = this.defaults.EnvironmentVariables;
}
else
{
@ -636,27 +632,27 @@ namespace WinSW.Configuration
}
string key = item.Name;
string value = ExpandEnv(item.Value);
string value = ExpandEnvironmentVariables(item.Value);
this.EnvironmentVariables[key] = value;
Environment.SetEnvironmentVariable(key, value);
SetEnvironmentVariable(key, value);
}
}
}
public ServiceAccount ServiceAccount => this.ServiceAccountYaml is null ? this.Defaults.ServiceAccount : this.ServiceAccountYaml;
public ServiceAccount ServiceAccount => this.ServiceAccountYaml is null ? this.defaults.ServiceAccount : this.ServiceAccountYaml;
public Log Log => this.YAMLLog is null ? this.Defaults.Log : this.YAMLLog;
public Log Log => this.YAMLLog is null ? this.defaults.Log : this.YAMLLog;
public string LogDirectory => this.Log.Directory;
public string LogMode => this.Log.Mode is null ? this.Defaults.LogMode : this.Log.Mode;
public string LogMode => this.Log.Mode is null ? this.defaults.LogMode : this.Log.Mode;
public XmlNode? ExtensionsConfiguration => null;
public XmlNode? XmlExtensions => null;
// YAML Extension
[YamlMember(Alias = "extensions")]
public List<YamlExtensionConfiguration>? YamlExtensionsConfiguration { get; set; }
public List<YamlExtensionConfig>? YamlExtensions { get; set; }
public List<string> ExtensionIds
{
@ -664,14 +660,14 @@ namespace WinSW.Configuration
{
int extensionNumber = 1;
if (this.YamlExtensionsConfiguration is null)
if (this.YamlExtensions is null)
{
return new List<string>(0);
}
var result = new List<string>(this.YamlExtensionsConfiguration.Count);
var result = new List<string>(this.YamlExtensions.Count);
foreach (var item in this.YamlExtensionsConfiguration)
foreach (var item in this.YamlExtensions)
{
try
{
@ -699,10 +695,10 @@ namespace WinSW.Configuration
{
if (this.SecurityDescriptorYaml is null)
{
return this.Defaults.SecurityDescriptor;
return this.defaults.SecurityDescriptor;
}
return ExpandEnv(this.SecurityDescriptorYaml);
return ExpandEnvironmentVariables(this.SecurityDescriptorYaml);
}
}
}

View File

@ -1,17 +1,15 @@
using System;
using System;
using System.IO;
using WinSW.Configuration;
using YamlDotNet.Serialization;
namespace WinSW
{
public class ServiceDescriptorYaml
public class YamlServiceConfigLoader
{
public readonly YamlConfiguration Configurations;
public readonly YamlServiceConfig Config;
public static DefaultWinSWSettings Defaults { get; } = new DefaultWinSWSettings();
public ServiceDescriptorYaml(string baseName, string directory)
public YamlServiceConfigLoader(string baseName, string directory)
{
string basepath = Path.Combine(directory, baseName);
@ -20,34 +18,34 @@ namespace WinSW
string file = reader.ReadToEnd();
var deserializer = new DeserializerBuilder().IgnoreUnmatchedProperties().Build();
this.Configurations = deserializer.Deserialize<YamlConfiguration>(file);
this.Config = deserializer.Deserialize<YamlServiceConfig>(file);
}
Environment.SetEnvironmentVariable("BASE", directory);
// ditto for ID
Environment.SetEnvironmentVariable("SERVICE_ID", this.Configurations.Name);
Environment.SetEnvironmentVariable("SERVICE_ID", this.Config.Name);
// New name
Environment.SetEnvironmentVariable(WinSWSystem.EnvVarNameExecutablePath, Defaults.ExecutablePath);
Environment.SetEnvironmentVariable(WinSWSystem.EnvVarNameExecutablePath, new DefaultSettings().ExecutablePath);
// Also inject system environment variables
Environment.SetEnvironmentVariable(WinSWSystem.EnvVarNameServiceId, this.Configurations.Name);
Environment.SetEnvironmentVariable(WinSWSystem.EnvVarNameServiceId, this.Config.Name);
this.Configurations.LoadEnvironmentVariables();
this.Config.LoadEnvironmentVariables();
}
public ServiceDescriptorYaml(YamlConfiguration configs)
public YamlServiceConfigLoader(YamlServiceConfig configs)
{
this.Configurations = configs;
this.Configurations.LoadEnvironmentVariables();
this.Config = configs;
this.Config.LoadEnvironmentVariables();
}
public static ServiceDescriptorYaml FromYaml(string yaml)
public static YamlServiceConfigLoader FromYaml(string yaml)
{
var deserializer = new DeserializerBuilder().IgnoreUnmatchedProperties().Build();
var configs = deserializer.Deserialize<YamlConfiguration>(yaml);
return new ServiceDescriptorYaml(configs);
var configs = deserializer.Deserialize<YamlServiceConfig>(yaml);
return new YamlServiceConfigLoader(configs);
}
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.IO;
using System.Net;
#if !VNEXT

View File

@ -11,12 +11,12 @@ 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(IWinSWConfiguration descriptor, XmlNode node)
public virtual void Configure(IServiceConfig descriptor, XmlNode node)
{
// Do nothing
}
public virtual void Configure(IWinSWConfiguration descriptor, YamlExtensionConfiguration config)
public virtual void Configure(IServiceConfig descriptor, YamlExtensionConfig config)
{
// Do nothing
}

View File

@ -28,14 +28,14 @@ namespace WinSW.Extensions
/// </summary>
/// <param name="descriptor">Service descriptor</param>
/// <param name="node">Configuration node</param>
void Configure(IWinSWConfiguration descriptor, XmlNode node);
void Configure(IServiceConfig descriptor, XmlNode node);
/// <summary>
/// Configure the extension from Yaml configuration
/// </summary>
/// <param name="descriptor">YamlConfiguration</param>
/// <param name="descriptor">Service descriptor</param>
/// <param name="config">Configuration Node</param>
void Configure(IWinSWConfiguration descriptor, YamlExtensionConfiguration config);
void Configure(IServiceConfig descriptor, YamlExtensionConfig config);
/// <summary>
/// Start handler. Called during startup of the service before the child process.

View File

@ -42,7 +42,7 @@ namespace WinSW.Extensions
return new WinSWExtensionDescriptor(id, className, enabled);
}
public static WinSWExtensionDescriptor FromYaml(YamlExtensionConfiguration config)
public static WinSWExtensionDescriptor FromYaml(YamlExtensionConfig config)
{
bool enabled = config.Enabled;
string className = config.GetClassName();

View File

@ -10,11 +10,11 @@ namespace WinSW.Extensions
{
public Dictionary<string, IWinSWExtension> Extensions { get; private set; }
public IWinSWConfiguration ServiceDescriptor { get; private set; }
public IServiceConfig ServiceDescriptor { get; private set; }
private static readonly ILog Log = LogManager.GetLogger(typeof(WinSWExtensionManager));
public WinSWExtensionManager(IWinSWConfiguration serviceDescriptor)
public WinSWExtensionManager(IServiceConfig serviceDescriptor)
{
this.ServiceDescriptor = serviceDescriptor;
this.Extensions = new Dictionary<string, IWinSWExtension>();
@ -127,7 +127,7 @@ namespace WinSW.Extensions
throw new ExtensionException(id, "Extension has been already loaded");
}
if (this.ServiceDescriptor.GetType() == typeof(ServiceDescriptor))
if (this.ServiceDescriptor.GetType() == typeof(XmlServiceConfig))
{
this.LoadExtensionFromXml(id);
}
@ -139,7 +139,7 @@ namespace WinSW.Extensions
private void LoadExtensionFromXml(string id)
{
var extensionsConfig = this.ServiceDescriptor.ExtensionsConfiguration;
var extensionsConfig = this.ServiceDescriptor.XmlExtensions;
var configNode = extensionsConfig is null ? null : extensionsConfig.SelectSingleNode("extension[@id='" + id + "'][1]") as XmlElement;
if (configNode is null)
{
@ -173,7 +173,7 @@ namespace WinSW.Extensions
private void LoadExtensionFromYaml(string id)
{
var extensionConfigList = this.ServiceDescriptor.YamlExtensionsConfiguration;
var extensionConfigList = this.ServiceDescriptor.YamlExtensions;
if (extensionConfigList is null)
{
@ -207,7 +207,7 @@ namespace WinSW.Extensions
Log.Warn("Extension is disabled: " + id);
}
YamlExtensionConfiguration GetYamlonfigById(List<YamlExtensionConfiguration> configs, string id)
YamlExtensionConfig GetYamlonfigById(List<YamlExtensionConfig> configs, string id)
{
foreach (var item in configs)
{

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Diagnostics;
#if VNEXT
using System.IO.Compression;

View File

@ -1,4 +1,4 @@
using System;
using System;
namespace WinSW
{

View File

@ -219,7 +219,7 @@ namespace WinSW.Util
bool succeeded = SetConsoleCtrlHandler(null, false); // inherited
Debug.Assert(succeeded);
succeeded = ConsoleApis.SetConsoleOutputCP(ConsoleApis.CP_UTF8);
succeeded = SetConsoleOutputCP(CP_UTF8);
Debug.Assert(succeeded);
try

View File

@ -7,6 +7,7 @@ using log4net;
using WinSW.Configuration;
using WinSW.Extensions;
using WinSW.Util;
using static System.Environment;
using static WinSW.Plugins.RunawayProcessKillerExtension.NativeMethods;
namespace WinSW.Plugins
@ -179,7 +180,7 @@ namespace WinSW.Plugins
return parameters.Environment;
}
public override void Configure(IWinSWConfiguration descriptor, XmlNode node)
public override void Configure(IServiceConfig descriptor, XmlNode node)
{
// We expect the upper logic to process any errors
// TODO: a better parser API for types would be useful
@ -192,17 +193,22 @@ namespace WinSW.Plugins
this.CheckWinSWEnvironmentVariable = checkWinSWEnvironmentVariable is null ? true : bool.Parse(checkWinSWEnvironmentVariable);
}
public override void Configure(IWinSWConfiguration descriptor, YamlExtensionConfiguration config)
public override void Configure(IServiceConfig descriptor, YamlExtensionConfig config)
{
var dict = config.GetSettings();
this.Pidfile = (string)dict["pidfile"];
this.StopTimeout = TimeSpan.FromMilliseconds(int.Parse((string)dict["stopTimeOut"]));
this.StopParentProcessFirst = bool.Parse((string)dict["StopParentFirst"]);
this.Pidfile = ExpandEnvironmentVariables((string)dict["pidfile"]);
string stopTimeOutConfig = ExpandEnvironmentVariables((string)dict["stopTimeOut"]);
this.StopTimeout = TimeSpan.FromMilliseconds(int.Parse(stopTimeOutConfig));
string StopParentProcessFirstConfig = ExpandEnvironmentVariables((string)dict["StopParentFirst"]);
this.StopParentProcessFirst = bool.Parse(StopParentProcessFirstConfig);
try
{
this.CheckWinSWEnvironmentVariable = bool.Parse((string)dict["checkWinSWEnvironmentVariable"]);
string CheckWinSWEnvironmentVariableConfig = ExpandEnvironmentVariables((string)dict["checkWinSWEnvironmentVariable"]);
this.CheckWinSWEnvironmentVariable = bool.Parse(CheckWinSWEnvironmentVariableConfig);
}
catch
{

View File

@ -27,7 +27,7 @@ namespace WinSW.Plugins
this._entries.Add(config);
}
public override void Configure(IWinSWConfiguration descriptor, XmlNode node)
public override void Configure(IServiceConfig descriptor, XmlNode node)
{
var mapNodes = XmlHelper.SingleNode(node, "mapping", false)!.SelectNodes("map");
if (mapNodes != null)
@ -43,7 +43,7 @@ namespace WinSW.Plugins
}
}
public override void Configure(IWinSWConfiguration descriptor, YamlExtensionConfiguration config)
public override void Configure(IServiceConfig descriptor, YamlExtensionConfig config)
{
var dict = config.GetSettings();

View File

@ -2,6 +2,7 @@
using System.IO;
using System.Xml;
using WinSW.Util;
using static System.Environment;
namespace WinSW.Plugins
{
@ -37,9 +38,11 @@ namespace WinSW.Plugins
throw new InvalidDataException("SharedDirectoryMapperConfig config error");
}
bool enableMapping = ConfigHelper.YamlBoolParse((string)dict["enabled"]);
string label = (string)dict["label"];
string uncPath = (string)dict["uncpath"];
string enableMappingConfig = ExpandEnvironmentVariables((string)dict["enabled"]);
bool enableMapping = ConfigHelper.YamlBoolParse(enableMappingConfig);
string label = ExpandEnvironmentVariables((string)dict["label"]);
string uncPath = ExpandEnvironmentVariables((string)dict["uncpath"]);
return new SharedDirectoryMapperConfig(enableMapping, label, uncPath);
}

View File

@ -40,7 +40,7 @@ namespace winswTests.Configuration
ServiceDescriptorAssert.AssertAllOptionalPropertiesAreDefault(desc);
}
private static ServiceDescriptor Load(string exampleName)
private static XmlServiceConfig Load(string exampleName)
{
string directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
while (true)
@ -59,7 +59,7 @@ namespace winswTests.Configuration
var dom = new XmlDocument();
dom.Load(path);
return new ServiceDescriptor(dom);
return new(dom);
}
}
}

View File

@ -177,7 +177,7 @@ namespace winswTests
}
}
private Download GetSingleEntry(ServiceDescriptor sd)
private Download GetSingleEntry(XmlServiceConfig sd)
{
var downloads = sd.Downloads.ToArray();
Assert.That(downloads.Length, Is.EqualTo(1), "Service Descriptor is expected to have only one entry");

View File

@ -14,8 +14,8 @@ namespace winswTests.Extensions
[TestFixture]
class RunawayProcessKillerExtensionTest : ExtensionTestBase
{
IWinSWConfiguration _testServiceDescriptor;
IWinSWConfiguration _testServiceDescriptorYaml;
IServiceConfig _testServiceDescriptor;
IServiceConfig _testServiceDescriptorYaml;
readonly string testExtension = GetExtensionClassNameWithAssembly(typeof(RunawayProcessKillerExtension));
@ -38,7 +38,7 @@ $@"<service>
</extension>
</extensions>
</service>";
this._testServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
this._testServiceDescriptor = XmlServiceConfig.FromXML(seedXml);
string seedYaml = $@"---
id: jenkins
@ -61,7 +61,7 @@ extensions:
stopTimeOut: 5000
StopParentFirst: true";
this._testServiceDescriptorYaml = ServiceDescriptorYaml.FromYaml(seedYaml).Configurations;
this._testServiceDescriptorYaml = YamlServiceConfigLoader.FromYaml(seedYaml).Config;
}
[Test]

View File

@ -9,8 +9,8 @@ namespace winswTests.Extensions
[TestFixture]
class SharedDirectoryMapperTest : ExtensionTestBase
{
IWinSWConfiguration _testServiceDescriptor;
IWinSWConfiguration _testServiceDescriptorYaml;
IServiceConfig _testServiceDescriptor;
IServiceConfig _testServiceDescriptorYaml;
readonly string testExtension = GetExtensionClassNameWithAssembly(typeof(SharedDirectoryMapper));
@ -40,7 +40,7 @@ $@"<service>
</extension>
</extensions>
</service>";
this._testServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
this._testServiceDescriptor = XmlServiceConfig.FromXML(seedXml);
string seedYaml = $@"---
id: jenkins
@ -78,7 +78,7 @@ extensions:
label: Y
uncpath: \\UNC2";
this._testServiceDescriptorYaml = ServiceDescriptorYaml.FromYaml(seedYaml).Configurations;
this._testServiceDescriptorYaml = YamlServiceConfigLoader.FromYaml(seedYaml).Config;
}
[Test]

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Diagnostics;
using System.ServiceProcess;
using NUnit.Framework;
@ -10,7 +10,7 @@ namespace winswTests
[TestFixture]
public class ServiceDescriptorTests
{
private ServiceDescriptor _extendedServiceDescriptor;
private XmlServiceConfig _extendedServiceDescriptor;
private const string ExpectedWorkingDirectory = @"Z:\Path\SubPath";
private const string Username = "User";
@ -38,7 +38,7 @@ $@"<service>
<workingdirectory>{ExpectedWorkingDirectory}</workingdirectory>
<logpath>C:\logs</logpath>
</service>";
this._extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
this._extendedServiceDescriptor = XmlServiceConfig.FromXML(seedXml);
}
[Test]
@ -69,7 +69,7 @@ $@"<service>
<logpath>C:\logs</logpath>
</service>";
this._extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
this._extendedServiceDescriptor = XmlServiceConfig.FromXML(seedXml);
Assert.That(() => this._extendedServiceDescriptor.StartMode, Throws.ArgumentException);
}
@ -95,7 +95,7 @@ $@"<service>
<logpath>C:\logs</logpath>
</service>";
this._extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
this._extendedServiceDescriptor = XmlServiceConfig.FromXML(seedXml);
Assert.That(this._extendedServiceDescriptor.StartMode, Is.EqualTo(ServiceStartMode.Manual));
}
@ -129,13 +129,13 @@ $@"<service>
[Test]
public void Priority()
{
var sd = ServiceDescriptor.FromXML("<service><id>test</id><priority>normal</priority></service>");
var sd = XmlServiceConfig.FromXML("<service><id>test</id><priority>normal</priority></service>");
Assert.That(sd.Priority, Is.EqualTo(ProcessPriorityClass.Normal));
sd = ServiceDescriptor.FromXML("<service><id>test</id><priority>idle</priority></service>");
sd = XmlServiceConfig.FromXML("<service><id>test</id><priority>idle</priority></service>");
Assert.That(sd.Priority, Is.EqualTo(ProcessPriorityClass.Idle));
sd = ServiceDescriptor.FromXML("<service><id>test</id></service>");
sd = XmlServiceConfig.FromXML("<service><id>test</id></service>");
Assert.That(sd.Priority, Is.EqualTo(ProcessPriorityClass.Normal));
}
@ -151,7 +151,7 @@ $@"<service>
const string seedXml = "<service>"
+ "<stopparentprocessfirst>false</stopparentprocessfirst>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
var serviceDescriptor = XmlServiceConfig.FromXML(seedXml);
Assert.That(serviceDescriptor.StopParentProcessFirst, Is.False);
}
@ -162,7 +162,7 @@ $@"<service>
const string seedXml = "<service>"
+ "<stoptimeout>60sec</stoptimeout>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
var serviceDescriptor = XmlServiceConfig.FromXML(seedXml);
Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromSeconds(60)));
}
@ -173,7 +173,7 @@ $@"<service>
const string seedXml = "<service>"
+ "<stoptimeout>10min</stoptimeout>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
var serviceDescriptor = XmlServiceConfig.FromXML(seedXml);
Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromMinutes(10)));
}
@ -184,7 +184,7 @@ $@"<service>
const string seedXml = "<service>"
+ "<logname>MyTestApp</logname>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
var serviceDescriptor = XmlServiceConfig.FromXML(seedXml);
Assert.That(serviceDescriptor.LogName, Is.EqualTo("MyTestApp"));
}
@ -195,7 +195,7 @@ $@"<service>
const string seedXml = "<service>"
+ "<outfiledisabled>true</outfiledisabled>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
var serviceDescriptor = XmlServiceConfig.FromXML(seedXml);
Assert.That(serviceDescriptor.Log.OutFileDisabled, Is.True);
}
@ -206,7 +206,7 @@ $@"<service>
const string seedXml = "<service>"
+ "<errfiledisabled>true</errfiledisabled>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
var serviceDescriptor = XmlServiceConfig.FromXML(seedXml);
Assert.That(serviceDescriptor.Log.ErrFileDisabled, Is.True);
}
@ -217,7 +217,7 @@ $@"<service>
const string seedXml = "<service>"
+ "<outfilepattern>.out.test.log</outfilepattern>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
var serviceDescriptor = XmlServiceConfig.FromXML(seedXml);
Assert.That(serviceDescriptor.Log.OutFilePattern, Is.EqualTo(".out.test.log"));
}
@ -228,7 +228,7 @@ $@"<service>
const string seedXml = "<service>"
+ "<errfilepattern>.err.test.log</errfilepattern>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
var serviceDescriptor = XmlServiceConfig.FromXML(seedXml);
Assert.That(serviceDescriptor.Log.ErrFilePattern, Is.EqualTo(".err.test.log"));
}
@ -244,7 +244,7 @@ $@"<service>
+ "</log>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
var serviceDescriptor = XmlServiceConfig.FromXML(seedXml);
serviceDescriptor.BaseName = "service";
var logHandler = serviceDescriptor.Log.CreateLogHandler() as SizeBasedRollingLogAppender;
@ -264,7 +264,7 @@ $@"<service>
+ "</log>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
var serviceDescriptor = XmlServiceConfig.FromXML(seedXml);
serviceDescriptor.BaseName = "service";
var logHandler = serviceDescriptor.Log.CreateLogHandler() as TimeBasedRollingLogAppender;
@ -285,7 +285,7 @@ $@"<service>
+ "</log>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
var serviceDescriptor = XmlServiceConfig.FromXML(seedXml);
serviceDescriptor.BaseName = "service";
var logHandler = serviceDescriptor.Log.CreateLogHandler() as RollingSizeTimeLogAppender;
@ -306,7 +306,7 @@ $@"<service>
+ "<allowservicelogon>true1</allowservicelogon>"
+ "</serviceaccount>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
var serviceDescriptor = XmlServiceConfig.FromXML(seedXml);
Assert.That(serviceDescriptor.ServiceAccount.AllowServiceAcountLogonRight, Is.False);
}
@ -320,7 +320,7 @@ $@"<service>
+ "<password>" + Password + "</password>"
+ "</serviceaccount>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
var serviceDescriptor = XmlServiceConfig.FromXML(seedXml);
Assert.That(serviceDescriptor.ServiceAccount.AllowServiceAcountLogonRight, Is.False);
}

View File

@ -9,7 +9,7 @@ namespace winswTests
{
class ServiceDescriptorYamlTest
{
private IWinSWConfiguration _extendedServiceDescriptor;
private IServiceConfig _extendedServiceDescriptor;
private const string ExpectedWorkingDirectory = @"Z:\Path\SubPath";
private const string Username = "User";
@ -37,7 +37,7 @@ serviceaccount:
allowservicelogon: {AllowServiceAccountLogonRight}
workingdirectory: {ExpectedWorkingDirectory}";
this._extendedServiceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
this._extendedServiceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
}
[Test]
@ -57,7 +57,7 @@ executable: node.exe
arguments: My Arguments
startMode: roll";
this._extendedServiceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
this._extendedServiceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(() => this._extendedServiceDescriptor.StartMode, Throws.ArgumentException);
}
@ -72,7 +72,7 @@ executable: node.exe
arguments: My Arguments
startMode: manual";
this._extendedServiceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
this._extendedServiceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(this._extendedServiceDescriptor.StartMode, Is.EqualTo(ServiceStartMode.Manual));
}
@ -106,27 +106,27 @@ startMode: manual";
[Test]
public void Priority()
{
var sd = ServiceDescriptorYaml.FromYaml(@"
var sd = YamlServiceConfigLoader.FromYaml(@"
id: service.exe
name: Service
description: The Service.
executable: node.exe
priority: normal").Configurations;
priority: normal").Config;
Assert.That(sd.Priority, Is.EqualTo(ProcessPriorityClass.Normal));
sd = ServiceDescriptorYaml.FromYaml(@"
sd = YamlServiceConfigLoader.FromYaml(@"
id: service.exe
name: Service
description: The Service.
executable: node.exe
priority: idle").Configurations;
priority: idle").Config;
Assert.That(sd.Priority, Is.EqualTo(ProcessPriorityClass.Idle));
sd = ServiceDescriptorYaml.FromYaml(@"
sd = YamlServiceConfigLoader.FromYaml(@"
id: service.exe
name: Service
description: The Service.
executable: node.exe").Configurations;
executable: node.exe").Config;
Assert.That(sd.Priority, Is.EqualTo(ProcessPriorityClass.Normal));
}
@ -145,7 +145,7 @@ name: Service
description: The Service.
executable: node.exe
stopParentProcessFirst: false";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.StopParentProcessFirst, Is.False);
}
@ -159,7 +159,7 @@ description: The Service.
executable: node.exe
stopTimeout: 60sec";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromSeconds(60)));
}
@ -174,7 +174,7 @@ description: The Service.
executable: node.exe
stopTimeout: 10min";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromMinutes(10)));
}
@ -190,7 +190,7 @@ executable: node.exe
log:
name: MyTestApp";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.Log.Name, Is.EqualTo("MyTestApp"));
}
@ -206,7 +206,7 @@ executable: node.exe
log:
outFileDisabled: true";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.Log.OutFileDisabled, Is.True);
}
@ -222,7 +222,7 @@ executable: node.exe
log:
errFileDisabled: true";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.Log.ErrFileDisabled, Is.True);
}
@ -238,7 +238,7 @@ executable: node.exe
log:
outFilePattern: .out.test.log";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.Log.OutFilePattern, Is.EqualTo(".out.test.log"));
}
@ -254,7 +254,7 @@ executable: node.exe
log:
errFilePattern: .err.test.log";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.Log.ErrFilePattern, Is.EqualTo(".err.test.log"));
}
@ -273,7 +273,7 @@ log:
sizeThreshold: 112
keepFiles: 113";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
serviceDescriptor.BaseName = "service";
@ -297,7 +297,7 @@ log:
period: 7
pattern: log pattern";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
serviceDescriptor.BaseName = "service";
@ -322,7 +322,7 @@ log:
pattern: yyyy-MM-dd
autoRollAtTime: 00:00:00";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
serviceDescriptor.BaseName = "service";
@ -347,7 +347,7 @@ serviceaccount:
password: {Password}
allowservicelogon: false";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.ServiceAccount.AllowServiceAcountLogonRight, Is.False);
}
@ -365,7 +365,7 @@ serviceaccount:
user: {Username}
password: {Password}";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.ServiceAccount.AllowServiceAcountLogonRight, Is.False);
}
@ -380,7 +380,7 @@ description: The Service.
executable: node.exe
waitHint: 20 min";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.WaitHint, Is.EqualTo(TimeSpan.FromMinutes(20)));
}
@ -395,7 +395,7 @@ description: The Service.
executable: node.exe
sleepTime: 3 hrs";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.SleepTime, Is.EqualTo(TimeSpan.FromHours(3)));
}
@ -410,7 +410,7 @@ description: The Service.
executable: node.exe
resetFailureAfter: 75 sec";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.ResetFailureAfter, Is.EqualTo(TimeSpan.FromSeconds(75)));
}
@ -425,7 +425,7 @@ description: The Service.
executable: node.exe
stopTimeout: 35 sec";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromSeconds(35)));
}
@ -440,7 +440,7 @@ description: The Service.
executable: node.exe
arguments: arg";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.Arguments, Is.EqualTo("arg"));
}
@ -454,7 +454,7 @@ description: The Service.
executable: node.exe
delayedAutoStart: true";
var serviceDescriptor = ServiceDescriptorYaml.FromYaml(yaml).Configurations;
var serviceDescriptor = YamlServiceConfigLoader.FromYaml(yaml).Config;
Assert.That(serviceDescriptor.DelayedAutoStart, Is.EqualTo(true));
}
@ -470,7 +470,7 @@ description: This is test winsw";
Assert.That(() =>
{
_ = ServiceDescriptorYaml.FromYaml(yml).Configurations.Name;
_ = YamlServiceConfigLoader.FromYaml(yml).Config.Name;
}, Throws.TypeOf<InvalidOperationException>());
}

View File

@ -25,7 +25,7 @@ $@"<service>
<logpath>C:\winsw\logs</logpath>
</service>";
public static readonly ServiceDescriptor DefaultServiceDescriptor = ServiceDescriptor.FromXML(SeedXml);
public static readonly XmlServiceConfig DefaultServiceDescriptor = XmlServiceConfig.FromXML(SeedXml);
/// <summary>
/// Runs a simle test, which returns the output CLI
@ -34,7 +34,7 @@ $@"<service>
/// <param name="descriptor">Optional Service descriptor (will be used for initializationpurposes)</param>
/// <returns>STDOUT if there's no exceptions</returns>
/// <exception cref="Exception">Command failure</exception>
public static string CLITest(string[] arguments, ServiceDescriptor descriptor = null)
public static string CLITest(string[] arguments, XmlServiceConfig descriptor = null)
{
var tmpOut = Console.Out;
var tmpErr = Console.Error;
@ -65,7 +65,7 @@ $@"<service>
/// <param name="arguments">CLI arguments to be passed</param>
/// <param name="descriptor">Optional Service descriptor (will be used for initializationpurposes)</param>
/// <returns>Test results</returns>
public static CLITestResult CLIErrorTest(string[] arguments, ServiceDescriptor descriptor = null)
public static CLITestResult CLIErrorTest(string[] arguments, XmlServiceConfig descriptor = null)
{
Exception testEx = null;
var tmpOut = Console.Out;

View File

@ -93,9 +93,9 @@ namespace winswTests.Util
return res;
}
public ServiceDescriptor ToServiceDescriptor(bool dumpConfig = false)
public XmlServiceConfig ToServiceDescriptor(bool dumpConfig = false)
{
return ServiceDescriptor.FromXML(this.ToXMLString(dumpConfig));
return XmlServiceConfig.FromXML(this.ToXMLString(dumpConfig));
}
public ConfigXmlBuilder WithRawEntry(string entry)

View File

@ -10,18 +10,18 @@ namespace winswTests.Util
// 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)
public static void AssertPropertyIsDefault(XmlServiceConfig desc, string property)
{
var actualProperty = typeof(ServiceDescriptor).GetProperty(property);
var actualProperty = typeof(XmlServiceConfig).GetProperty(property);
Assert.That(actualProperty, Is.Not.Null);
var defaultProperty = typeof(DefaultWinSWSettings).GetProperty(property);
var defaultProperty = typeof(DefaultSettings).GetProperty(property);
Assert.That(defaultProperty, Is.Not.Null);
Assert.That(actualProperty.GetValue(desc, null), Is.EqualTo(defaultProperty.GetValue(ServiceDescriptor.Defaults, null)));
Assert.That(actualProperty.GetValue(desc, null), Is.EqualTo(defaultProperty.GetValue(XmlServiceConfig.Defaults, null)));
}
public static void AssertPropertyIsDefault(ServiceDescriptor desc, List<string> properties)
public static void AssertPropertyIsDefault(XmlServiceConfig desc, List<string> properties)
{
foreach (string prop in properties)
{
@ -29,7 +29,7 @@ namespace winswTests.Util
}
}
public static void AssertAllOptionalPropertiesAreDefault(ServiceDescriptor desc)
public static void AssertAllOptionalPropertiesAreDefault(XmlServiceConfig desc)
{
AssertPropertyIsDefault(desc, AllOptionalProperties);
}
@ -39,7 +39,7 @@ namespace winswTests.Util
get
{
var res = new List<string>();
var properties = typeof(IWinSWConfiguration).GetProperties();
var properties = typeof(IServiceConfig).GetProperties();
foreach (var prop in properties)
{
res.Add(prop.Name);
@ -54,14 +54,14 @@ namespace winswTests.Util
get
{
var properties = AllProperties;
properties.Remove(nameof(IWinSWConfiguration.Name));
properties.Remove(nameof(IWinSWConfiguration.DisplayName));
properties.Remove(nameof(IWinSWConfiguration.Description));
properties.Remove(nameof(IWinSWConfiguration.Executable));
properties.Remove(nameof(IWinSWConfiguration.BaseName));
properties.Remove(nameof(IWinSWConfiguration.BasePath));
properties.Remove(nameof(IWinSWConfiguration.Log));
properties.Remove(nameof(IWinSWConfiguration.ServiceAccount));
properties.Remove(nameof(IServiceConfig.Name));
properties.Remove(nameof(IServiceConfig.DisplayName));
properties.Remove(nameof(IServiceConfig.Description));
properties.Remove(nameof(IServiceConfig.Executable));
properties.Remove(nameof(IServiceConfig.BaseName));
properties.Remove(nameof(IServiceConfig.BasePath));
properties.Remove(nameof(IServiceConfig.Log));
properties.Remove(nameof(IServiceConfig.ServiceAccount));
return properties;
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net40;net461;net5.0-windows</TargetFrameworks>

View File

@ -5,7 +5,7 @@ namespace WinSW
{
internal static class FormatExtensions
{
internal static string Format(IWinSWConfiguration config)
internal static string Format(IServiceConfig config)
{
string name = config.Name;
string displayName = config.DisplayName;

View File

@ -82,17 +82,16 @@ namespace WinSW
}
}
public static void Run(string[] argsArray, IWinSWConfiguration? descriptor = null)
public static void Run(string[] argsArray, IServiceConfig? config = null)
{
bool inConsoleMode = argsArray.Length > 0;
// If descriptor is not specified, initialize the new one (and load configs from there)
descriptor ??= LoadConfigAndInitLoggers(inConsoleMode);
config ??= LoadConfigAndInitLoggers(inConsoleMode);
if (!inConsoleMode)
{
Log.Debug("Starting WinSW in service mode");
using var service = new WrapperService(descriptor);
using var service = new WrapperService(config);
try
{
ServiceBase.Run(service);
@ -244,14 +243,14 @@ namespace WinSW
return;
}
Log.Info($"Installing service '{Format(descriptor)}'...");
Log.Info($"Installing service '{Format(config)}'...");
using var scm = ServiceManager.Open(ServiceManagerAccess.CreateService);
if (scm.ServiceExists(descriptor.Name))
if (scm.ServiceExists(config.Name))
{
Log.Error($"A service with ID '{descriptor.Name}' already exists.");
Log.Error($"A service with ID '{config.Name}' already exists.");
Throw.Command.Win32Exception(Errors.ERROR_SERVICE_EXISTS, "Failed to install the service.");
}
@ -271,61 +270,61 @@ namespace WinSW
}
else
{
if (descriptor.ServiceAccount.HasServiceAccount())
if (config.ServiceAccount.HasServiceAccount())
{
username = descriptor.ServiceAccount.ServiceAccountUser;
password = descriptor.ServiceAccount.ServiceAccountPassword;
allowServiceLogonRight = descriptor.ServiceAccount.AllowServiceAcountLogonRight;
username = config.ServiceAccount.ServiceAccountUser;
password = config.ServiceAccount.ServiceAccountPassword;
allowServiceLogonRight = config.ServiceAccount.AllowServiceAcountLogonRight;
}
}
if (allowServiceLogonRight)
{
Security.AddServiceLogonRight(descriptor.ServiceAccount.ServiceAccountDomain!, descriptor.ServiceAccount.ServiceAccountName!);
Security.AddServiceLogonRight(config.ServiceAccount.ServiceAccountDomain!, config.ServiceAccount.ServiceAccountName!);
}
using var sc = scm.CreateService(
descriptor.Name,
descriptor.DisplayName,
descriptor.Interactive,
descriptor.StartMode,
$"\"{descriptor.ExecutablePath}\"",
descriptor.ServiceDependencies,
config.Name,
config.DisplayName,
config.Interactive,
config.StartMode,
$"\"{config.ExecutablePath}\"",
config.ServiceDependencies,
username,
password);
string description = descriptor.Description;
string description = config.Description;
if (description.Length != 0)
{
sc.SetDescription(description);
}
var actions = descriptor.FailureActions;
var 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);
}
string? securityDescriptor = descriptor.SecurityDescriptor;
string? securityDescriptor = config.SecurityDescriptor;
if (securityDescriptor != null)
{
// throws ArgumentException
sc.SetSecurityDescriptor(new RawSecurityDescriptor(securityDescriptor));
}
string eventLogSource = descriptor.Name;
string eventLogSource = config.Name;
if (!EventLog.SourceExists(eventLogSource))
{
EventLog.CreateEventSource(eventLogSource, "Application");
}
Log.Info($"Service '{Format(descriptor)}' was installed successfully.");
Log.Info($"Service '{Format(config)}' was installed successfully.");
}
void Uninstall()
@ -336,30 +335,30 @@ namespace WinSW
return;
}
Log.Info($"Uninstalling service '{Format(descriptor)}'...");
Log.Info($"Uninstalling service '{Format(config)}'...");
using var scm = ServiceManager.Open(ServiceManagerAccess.Connect);
try
{
using var sc = scm.OpenService(descriptor.Name);
using var sc = scm.OpenService(config.Name);
if (sc.Status != ServiceControllerStatus.Stopped)
{
// We could fail the opeartion here, but it would be an incompatible change.
// So it is just a warning
Log.Warn($"Service '{Format(descriptor)}' is started. It may be impossible to uninstall it.");
Log.Warn($"Service '{Format(config)}' is started. It may be impossible to uninstall it.");
}
sc.Delete();
Log.Info($"Service '{Format(descriptor)}' was uninstalled successfully.");
Log.Info($"Service '{Format(config)}' was uninstalled successfully.");
}
catch (CommandException e) when (e.InnerException is Win32Exception inner)
{
switch (inner.NativeErrorCode)
{
case Errors.ERROR_SERVICE_DOES_NOT_EXIST:
Log.Warn($"Service '{Format(descriptor)}' does not exist.");
Log.Warn($"Service '{Format(config)}' does not exist.");
break; // there's no such service, so consider it already uninstalled
case Errors.ERROR_SERVICE_MARKED_FOR_DELETE:
@ -383,7 +382,7 @@ namespace WinSW
return;
}
using var svc = new ServiceController(descriptor.Name);
using var svc = new ServiceController(config.Name);
try
{
@ -412,7 +411,7 @@ namespace WinSW
return;
}
using var svc = new ServiceController(descriptor.Name);
using var svc = new ServiceController(config.Name);
try
{
@ -454,7 +453,7 @@ namespace WinSW
}
using var svc = new ServiceController(descriptor.Name);
using var svc = new ServiceController(config.Name);
List<ServiceController>? startedDependentServices = null;
@ -528,12 +527,12 @@ namespace WinSW
Throw.Command.Win32Exception(Errors.ERROR_ACCESS_DENIED);
}
Log.Info("Restarting the service with id '" + descriptor.Name + "'");
Log.Info("Restarting the service with id '" + config.Name + "'");
// run restart from another process group. see README.md for why this is useful.
if (!ProcessApis.CreateProcess(
null,
descriptor.ExecutablePath + " restart",
config.ExecutablePath + " restart",
IntPtr.Zero,
IntPtr.Zero,
false,
@ -552,7 +551,7 @@ namespace WinSW
void Status()
{
using var svc = new ServiceController(descriptor.Name);
using var svc = new ServiceController(config.Name);
try
{
Console.WriteLine(svc.Status != ServiceControllerStatus.Stopped ? "Started" : "Stopped");
@ -572,7 +571,7 @@ namespace WinSW
return;
}
var wsvc = new WrapperService(descriptor);
var wsvc = new WrapperService(config);
wsvc.RaiseOnStart(args.ToArray());
Thread.Sleep(1000);
wsvc.RaiseOnStop();
@ -586,7 +585,7 @@ namespace WinSW
return;
}
var wsvc = new WrapperService(descriptor);
var wsvc = new WrapperService(config);
wsvc.RaiseOnStart(args.ToArray());
Console.WriteLine("Press any key to stop the service...");
_ = Console.Read();
@ -660,7 +659,7 @@ namespace WinSW
}
}
private static IWinSWConfiguration LoadConfigAndInitLoggers(bool inConsoleMode)
private static IServiceConfig LoadConfigAndInitLoggers(bool inConsoleMode)
{
// TODO: Make logging levels configurable
var fileLogLevel = Level.Debug;
@ -703,9 +702,9 @@ namespace WinSW
string directory = Path.GetDirectoryName(executablePath)!;
string baseName = Path.GetFileNameWithoutExtension(executablePath);
IWinSWConfiguration config =
File.Exists(Path.Combine(directory, baseName + ".xml")) ? new ServiceDescriptor(baseName, directory) :
File.Exists(Path.Combine(directory, baseName + ".yml")) ? new ServiceDescriptorYaml(baseName, directory).Configurations :
IServiceConfig config =
File.Exists(Path.Combine(directory, baseName + ".xml")) ? new XmlServiceConfig(baseName, directory) :
File.Exists(Path.Combine(directory, baseName + ".yml")) ? new YamlServiceConfigLoader(baseName, directory).Config :
throw new FileNotFoundException($"Unable to locate {baseName}.[xml|yml] file within executable directory");
// .wrapper.log

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@ -22,7 +22,7 @@ namespace WinSW
{
private readonly Process process = new();
private readonly IWinSWConfiguration descriptor;
private readonly IServiceConfig config;
private Dictionary<string, string>? envs;
@ -52,11 +52,11 @@ namespace WinSW
/// </summary>
public bool IsShuttingDown => this.shuttingdown;
public WrapperService(IWinSWConfiguration descriptor)
public WrapperService(IServiceConfig config)
{
this.descriptor = descriptor;
this.ServiceName = this.descriptor.Name;
this.ExtensionManager = new WinSWExtensionManager(this.descriptor);
this.config = config;
this.ServiceName = this.config.Name;
this.ExtensionManager = new WinSWExtensionManager(this.config);
this.CanShutdown = true;
this.CanStop = true;
this.CanPauseAndContinue = false;
@ -73,7 +73,7 @@ namespace WinSW
/// </summary>
private void HandleFileCopies()
{
string file = this.descriptor.BasePath + ".copies";
string file = this.config.BasePath + ".copies";
if (!File.Exists(file))
{
return; // nothing to handle
@ -123,14 +123,14 @@ namespace WinSW
/// <returns>Log Handler, which should be used for the spawned process</returns>
private LogHandler CreateExecutableLogHandler()
{
string? logDirectory = this.descriptor.LogDirectory;
string? logDirectory = this.config.LogDirectory;
if (!Directory.Exists(logDirectory))
{
Directory.CreateDirectory(logDirectory);
}
var logAppender = this.descriptor.Log.CreateLogHandler();
var logAppender = this.config.Log.CreateLogHandler();
logAppender.EventLogger = this;
return logAppender;
@ -222,7 +222,7 @@ namespace WinSW
bool succeeded = ConsoleApis.SetConsoleCtrlHandler(null, true);
Debug.Assert(succeeded);
this.envs = this.descriptor.EnvironmentVariables;
this.envs = this.config.EnvironmentVariables;
// TODO: Disabled according to security concerns in https://github.com/kohsuke/winsw/issues/54
// Could be restored, but unlikely it's required in event logs at all
@ -235,7 +235,7 @@ namespace WinSW
// handle downloads
#if VNEXT
var downloads = this.descriptor.Downloads;
var downloads = this.config.Downloads;
var tasks = new Task[downloads.Count];
for (int i = 0; i < downloads.Count; i++)
{
@ -274,7 +274,7 @@ namespace WinSW
throw new AggregateException(exceptions);
}
#else
foreach (var download in this.descriptor.Downloads)
foreach (var download in this.config.Downloads)
{
string downloadMessage = $"Downloading: {download.From} to {download.To}. failOnError={download.FailOnError.ToString()}";
this.LogEvent(downloadMessage);
@ -300,15 +300,15 @@ namespace WinSW
}
#endif
string? startArguments = this.descriptor.StartArguments;
string? startArguments = this.config.StartArguments;
if (startArguments is null)
{
startArguments = this.descriptor.Arguments;
startArguments = this.config.Arguments;
}
else
{
startArguments += " " + this.descriptor.Arguments;
startArguments += " " + this.config.Arguments;
}
// Converting newlines, line returns, tabs into a single
@ -316,15 +316,15 @@ namespace WinSW
// in the xml for readability.
startArguments = Regex.Replace(startArguments, @"\s*[\n\r]+\s*", " ");
this.LogEvent("Starting " + this.descriptor.Executable + ' ' + startArguments);
Log.Info("Starting " + this.descriptor.Executable + ' ' + startArguments);
this.LogEvent("Starting " + this.config.Executable + ' ' + startArguments);
Log.Info("Starting " + this.config.Executable + ' ' + startArguments);
// Load and start extensions
this.ExtensionManager.LoadExtensions();
this.ExtensionManager.FireOnWrapperStarted();
var 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);
}
@ -333,9 +333,9 @@ namespace WinSW
/// </summary>
private void DoStop()
{
string? stopArguments = this.descriptor.StopArguments;
this.LogEvent("Stopping " + this.descriptor.Name);
Log.Info("Stopping " + this.descriptor.Name);
string? stopArguments = this.config.StopArguments;
this.LogEvent("Stopping " + this.config.Name);
Log.Info("Stopping " + this.config.Name);
this.orderlyShutdown = true;
if (stopArguments is null)
@ -343,7 +343,7 @@ namespace WinSW
try
{
Log.Debug("ProcessKill " + this.process.Id);
ProcessHelper.StopProcessTree(this.process, this.descriptor.StopTimeout, this.descriptor.StopParentProcessFirst);
ProcessHelper.StopProcessTree(this.process, this.config.StopTimeout, this.config.StopParentProcessFirst);
this.ExtensionManager.FireOnProcessTerminated(this.process);
}
catch (InvalidOperationException)
@ -355,12 +355,12 @@ namespace WinSW
{
this.SignalPending();
stopArguments += " " + this.descriptor.Arguments;
stopArguments += " " + this.config.Arguments;
var stopProcess = new Process();
string? executable = this.descriptor.StopExecutable;
string? executable = this.config.StopExecutable;
executable ??= this.descriptor.Executable;
executable ??= this.config.Executable;
// TODO: Redirect logging to Log4Net once https://github.com/kohsuke/winsw/pull/213 is integrated
this.StartProcess(stopProcess, stopArguments, executable, null);
@ -373,12 +373,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.Name);
Log.Info("Finished " + this.config.Name);
}
private void WaitForProcessToExit(Process processoWait)
@ -386,15 +386,15 @@ namespace WinSW
this.SignalPending();
int effectiveProcessWaitSleepTime;
if (this.descriptor.SleepTime.TotalMilliseconds > int.MaxValue)
if (this.config.SleepTime.TotalMilliseconds > int.MaxValue)
{
Log.Warn("The requested sleep time " + this.descriptor.SleepTime.TotalMilliseconds + "is greater that the max value " +
Log.Warn("The requested sleep time " + this.config.SleepTime.TotalMilliseconds + "is greater that the max value " +
int.MaxValue + ". The value will be truncated");
effectiveProcessWaitSleepTime = int.MaxValue;
}
else
{
effectiveProcessWaitSleepTime = (int)this.descriptor.SleepTime.TotalMilliseconds;
effectiveProcessWaitSleepTime = (int)this.config.SleepTime.TotalMilliseconds;
}
try
@ -418,15 +418,15 @@ namespace WinSW
private void SignalPending()
{
int effectiveWaitHint;
if (this.descriptor.WaitHint.TotalMilliseconds > int.MaxValue)
if (this.config.WaitHint.TotalMilliseconds > int.MaxValue)
{
Log.Warn("The requested WaitHint value (" + this.descriptor.WaitHint.TotalMilliseconds + " ms) is greater that the max value " +
Log.Warn("The requested WaitHint value (" + this.config.WaitHint.TotalMilliseconds + " ms) is greater that the max value " +
int.MaxValue + ". The value will be truncated");
effectiveWaitHint = int.MaxValue;
}
else
{
effectiveWaitHint = (int)this.descriptor.WaitHint.TotalMilliseconds;
effectiveWaitHint = (int)this.config.WaitHint.TotalMilliseconds;
}
this.RequestAdditionalTime(effectiveWaitHint);
@ -483,11 +483,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,
callback: OnProcessCompleted,
logHandler: logHandler,
hideWindow: this.descriptor.HideWindow);
hideWindow: this.config.HideWindow);
}
}
}