From e116368fc441d6f677435003400071da291f1332 Mon Sep 17 00:00:00 2001 From: NextTurn <45985406+NextTurn@users.noreply.github.com> Date: Wed, 8 Jul 2020 00:00:00 +0800 Subject: [PATCH] Standardize coding styles --- Directory.Build.props | 5 + src/.editorconfig | 64 ++++++ .../Logging/WrapperServiceEventLogProvider.cs | 12 +- src/Core/ServiceWrapper/Program.cs | 16 +- src/Core/ServiceWrapper/WrapperService.cs | 202 +++++++++-------- .../Configuration/DefaultSettings.cs | 41 +++- .../Configuration/IWinSWConfiguration.cs | 25 +- src/Core/WinSWCore/Download.cs | 99 ++++---- src/Core/WinSWCore/DynamicProxy.cs | 8 +- .../Extensions/AbstractWinSWExtension.cs | 2 +- .../Extensions/ExtensionException.cs | 8 +- .../Extensions/ExtensionPointAttribute.cs | 4 +- .../WinSWCore/Extensions/IWinSWExtension.cs | 2 +- .../Extensions/WinSWExtensionDescriptor.cs | 10 +- .../Extensions/WinSWExtensionManager.cs | 31 ++- src/Core/WinSWCore/LogAppenders.cs | 213 ++++++++++-------- .../Logging/IServiceEventLogProvider.cs | 4 +- .../Logging/ServiceEventLogAppender.cs | 12 +- src/Core/WinSWCore/Native/ConsoleApis.cs | 6 +- src/Core/WinSWCore/Native/Errors.cs | 4 +- src/Core/WinSWCore/Native/HandleApis.cs | 2 +- src/Core/WinSWCore/Native/Kernel32.cs | 2 +- src/Core/WinSWCore/Native/Libraries.cs | 2 +- src/Core/WinSWCore/Native/ProcessApis.cs | 6 +- src/Core/WinSWCore/Native/Security.cs | 4 +- src/Core/WinSWCore/Native/SecurityApis.cs | 6 +- src/Core/WinSWCore/Native/Service.cs | 7 +- src/Core/WinSWCore/Native/ServiceApis.cs | 2 +- src/Core/WinSWCore/Native/Throw.cs | 2 +- src/Core/WinSWCore/NullableAttributes.cs | 1 + src/Core/WinSWCore/PeriodicRollingCalendar.cs | 76 +++---- src/Core/WinSWCore/ServiceDescriptor.cs | 184 ++++++++------- src/Core/WinSWCore/Util/FileHelper.cs | 2 +- src/Core/WinSWCore/Util/ProcessHelper.cs | 10 +- src/Core/WinSWCore/Util/SignalHelper.cs | 4 +- src/Core/WinSWCore/Util/XmlHelper.cs | 13 +- src/Core/WinSWCore/WinSWCore.csproj | 4 + src/Core/WinSWCore/WinSWException.cs | 8 +- src/Core/WinSWCore/WinSWSystem.cs | 8 +- src/Core/WinSWCore/Wmi.cs | 18 +- src/Core/WinSWCore/WmiSchema.cs | 16 +- .../RunawayProcessKiller/NativeMethods.cs | 2 +- .../RunawayProcessKillerExtension.cs | 44 ++-- .../SharedDirectoryMapper.cs | 28 +-- .../SharedDirectoryMapperConfig.cs | 10 +- .../SharedDirectoryMapperHelper.cs | 10 +- .../winswTests/Configuration/ExamplesTest.cs | 2 +- src/Test/winswTests/DownloadConfigTests.cs | 42 ++-- src/Test/winswTests/DownloadTests.cs | 6 +- .../Extensions/RunawayProcessKillerTest.cs | 18 +- .../Extensions/SharedDirectoryMapperTest.cs | 16 +- src/Test/winswTests/MainTest.cs | 2 +- src/Test/winswTests/ServiceDescriptorTests.cs | 30 +-- src/Test/winswTests/Util/CLITestHelper.cs | 10 +- src/Test/winswTests/Util/ConfigXmlBuilder.cs | 44 ++-- src/Test/winswTests/Util/ProcessHelperTest.cs | 2 +- .../Util/ServiceDescriptorAssert.cs | 4 +- src/Test/winswTests/Util/TestHelper.cs | 2 +- src/stylecop.json | 7 + src/winsw.sln | 1 + src/winsw.sln.DotSettings | 3 - 61 files changed, 820 insertions(+), 608 deletions(-) create mode 100644 src/.editorconfig create mode 100644 src/stylecop.json delete mode 100644 src/winsw.sln.DotSettings diff --git a/Directory.Build.props b/Directory.Build.props index b3cf3c1..402beb4 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,8 +1,13 @@  + true full $(MSBuildThisFileDirectory)artifacts\ + + + + diff --git a/src/.editorconfig b/src/.editorconfig new file mode 100644 index 0000000..8a11138 --- /dev/null +++ b/src/.editorconfig @@ -0,0 +1,64 @@ +[*.cs] + +# SA0001: XML comment analysis is disabled due to project configuration +dotnet_diagnostic.SA0001.severity = none + +# SA1114: Parameter list should follow declaration +dotnet_diagnostic.SA1114.severity = none + +# SA1124: Do not use regions +dotnet_diagnostic.SA1124.severity = none + +# SA1201: Elements should appear in the correct order +dotnet_diagnostic.SA1201.severity = none + +# SA1202: Elements should be ordered by access +dotnet_diagnostic.SA1202.severity = none + +# SA1401: Fields should be private +dotnet_diagnostic.SA1401.severity = none + +# SA1402: File may only contain a single type +dotnet_diagnostic.SA1402.severity = none + +# SA1405: Debug.Assert should provide message text +dotnet_diagnostic.SA1405.severity = none + +# SA1413: Use trailing comma in multi-line initializers +dotnet_diagnostic.SA1413.severity = none + +# SA1600: Elements should be documented +dotnet_diagnostic.SA1600.severity = none + +# SA1602: Enumeration items should be documented +dotnet_diagnostic.SA1602.severity = none + +# SA1604: Element documentation should have summary +dotnet_diagnostic.SA1604.severity = none + +# SA1606: Element documentation should have summary text +dotnet_diagnostic.SA1606.severity = none + +# SA1611: Element parameters should be documented +dotnet_diagnostic.SA1611.severity = none + +# SA1615: Element return value should be documented +dotnet_diagnostic.SA1615.severity = none + +# SA1618: Generic type parameters should be documented +dotnet_diagnostic.SA1618.severity = none + +# SA1623: Property summary documentation should match accessors +dotnet_diagnostic.SA1623.severity = none + +# SA1629: Documentation text should end with a period +dotnet_diagnostic.SA1629.severity = none + +# SA1633: File should have header +dotnet_diagnostic.SA1633.severity = none + +# SA1642: Constructor summary documentation should begin with standard text +dotnet_diagnostic.SA1642.severity = none + +# SA1649: File name should match first type name +dotnet_diagnostic.SA1649.severity = none diff --git a/src/Core/ServiceWrapper/Logging/WrapperServiceEventLogProvider.cs b/src/Core/ServiceWrapper/Logging/WrapperServiceEventLogProvider.cs index be7cad5..462b419 100644 --- a/src/Core/ServiceWrapper/Logging/WrapperServiceEventLogProvider.cs +++ b/src/Core/ServiceWrapper/Logging/WrapperServiceEventLogProvider.cs @@ -1,20 +1,20 @@ using System.Diagnostics; -namespace winsw.Logging +namespace WinSW.Logging { /// /// Implements caching of the WindowsService reference in WinSW. /// public class WrapperServiceEventLogProvider : IServiceEventLogProvider { - public WrapperService? service { get; set; } + public WrapperService? Service { get; set; } - public EventLog? locate() + public EventLog? Locate() { - WrapperService? _service = service; - if (_service != null && !_service.IsShuttingDown) + WrapperService? service = this.Service; + if (service != null && !service.IsShuttingDown) { - return _service.EventLog; + return service.EventLog; } // By default return null diff --git a/src/Core/ServiceWrapper/Program.cs b/src/Core/ServiceWrapper/Program.cs index f03fd77..661a2f5 100644 --- a/src/Core/ServiceWrapper/Program.cs +++ b/src/Core/ServiceWrapper/Program.cs @@ -18,13 +18,13 @@ using log4net.Appender; using log4net.Config; using log4net.Core; using log4net.Layout; -using winsw.Logging; -using winsw.Native; -using winsw.Util; +using WinSW.Logging; +using WinSW.Native; +using WinSW.Util; using WMI; using ServiceType = WMI.ServiceType; -namespace winsw +namespace WinSW { public static class Program { @@ -86,8 +86,8 @@ namespace winsw } // Get service info for the future use - Win32Services svcs = new WmiRoot().GetCollection(); - Win32Service? svc = svcs.Select(descriptor.Id); + IWin32Services svcs = new WmiRoot().GetCollection(); + IWin32Service? svc = svcs.Select(descriptor.Id); var args = new List(Array.AsReadOnly(argsArray)); if (args[0] == "/redirect") @@ -452,7 +452,6 @@ namespace winsw Log.Info("Restarting the service with id '" + descriptor.Id + "'"); // run restart from another process group. see README.md for why this is useful. - bool result = ProcessApis.CreateProcess(null, descriptor.ExecutablePath + " restart", IntPtr.Zero, IntPtr.Zero, false, ProcessApis.CREATE_NEW_PROCESS_GROUP, IntPtr.Zero, null, default, out _); if (!result) { @@ -537,6 +536,7 @@ namespace winsw { // TODO: Make logging levels configurable Level fileLogLevel = Level.Debug; + // TODO: Debug should not be printed to console by default. Otherwise commands like 'status' will be pollutted // This is a workaround till there is a better command line parsing, which will allow determining Level consoleLogLevel = Level.Info; @@ -581,7 +581,7 @@ namespace winsw { Name = "Wrapper event log", Threshold = eventLogLevel, - provider = WrapperService.eventLogProvider, + Provider = WrapperService.eventLogProvider, }; systemEventLogger.ActivateOptions(); appenders.Add(systemEventLogger); diff --git a/src/Core/ServiceWrapper/WrapperService.cs b/src/Core/ServiceWrapper/WrapperService.cs index af3a972..a8a3ed8 100644 --- a/src/Core/ServiceWrapper/WrapperService.cs +++ b/src/Core/ServiceWrapper/WrapperService.cs @@ -10,20 +10,20 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; #endif using log4net; -using winsw.Extensions; -using winsw.Logging; -using winsw.Native; -using winsw.Util; +using WinSW.Extensions; +using WinSW.Logging; +using WinSW.Native; +using WinSW.Util; -namespace winsw +namespace WinSW { - public class WrapperService : ServiceBase, EventLogger + public class WrapperService : ServiceBase, IEventLogger { - private ServiceApis.SERVICE_STATUS _wrapperServiceStatus; + private ServiceApis.SERVICE_STATUS wrapperServiceStatus; - private readonly Process _process = new Process(); - private readonly ServiceDescriptor _descriptor; - private Dictionary? _envs; + private readonly Process process = new Process(); + private readonly ServiceDescriptor descriptor; + private Dictionary? envs; internal WinSWExtensionManager ExtensionManager { get; private set; } @@ -32,14 +32,15 @@ namespace winsw Assembly.GetExecutingAssembly(), #endif "WinSW"); + internal static readonly WrapperServiceEventLogProvider eventLogProvider = new WrapperServiceEventLogProvider(); /// /// Indicates to the watch dog thread that we are going to terminate the process, /// so don't try to kill us when the child exits. /// - private bool _orderlyShutdown; - private bool _systemShuttingdown; + private bool orderlyShutdown; + private bool systemShuttingdown; /// /// Version of Windows service wrapper @@ -52,24 +53,25 @@ namespace winsw /// /// Indicates that the system is shutting down. /// - public bool IsShuttingDown => _systemShuttingdown; + public bool IsShuttingDown => this.systemShuttingdown; public WrapperService(ServiceDescriptor descriptor) { - _descriptor = descriptor; - ServiceName = _descriptor.Id; - ExtensionManager = new WinSWExtensionManager(_descriptor); - CanShutdown = true; - CanStop = true; - CanPauseAndContinue = false; - AutoLog = true; - _systemShuttingdown = false; + this.descriptor = descriptor; + this.ServiceName = this.descriptor.Id; + this.ExtensionManager = new WinSWExtensionManager(this.descriptor); + this.CanShutdown = true; + this.CanStop = true; + this.CanPauseAndContinue = false; + this.AutoLog = true; + this.systemShuttingdown = false; // Register the event log provider - eventLogProvider.service = this; + eventLogProvider.Service = this; } - public WrapperService() : this(new ServiceDescriptor()) + public WrapperService() + : this(new ServiceDescriptor()) { } @@ -79,9 +81,11 @@ namespace winsw /// private void HandleFileCopies() { - var file = _descriptor.BasePath + ".copies"; + var file = this.descriptor.BasePath + ".copies"; if (!File.Exists(file)) + { return; // nothing to handle + } try { @@ -89,15 +93,15 @@ namespace winsw string? line; while ((line = tr.ReadLine()) != null) { - LogEvent("Handling copy: " + line); + this.LogEvent("Handling copy: " + line); string[] tokens = line.Split('>'); if (tokens.Length > 2) { - LogEvent("Too many delimiters in " + line); + this.LogEvent("Too many delimiters in " + line); continue; } - MoveFile(tokens[0], tokens[1]); + this.MoveFile(tokens[0], tokens[1]); } } finally @@ -117,7 +121,7 @@ namespace winsw } catch (IOException e) { - LogEvent("Failed to move :" + sourceFileName + " to " + destFileName + " because " + e.Message); + this.LogEvent("Failed to move :" + sourceFileName + " to " + destFileName + " because " + e.Message); } } @@ -127,21 +131,21 @@ namespace winsw /// Log Handler, which should be used for the spawned process private LogHandler CreateExecutableLogHandler() { - string logDirectory = _descriptor.LogDirectory; + string logDirectory = this.descriptor.LogDirectory; if (!Directory.Exists(logDirectory)) { Directory.CreateDirectory(logDirectory); } - LogHandler logAppender = _descriptor.LogHandler; + LogHandler logAppender = this.descriptor.LogHandler; logAppender.EventLogger = this; return logAppender; } public void LogEvent(string message) { - if (_systemShuttingdown) + if (this.systemShuttingdown) { /* NOP - cannot call EventLog because of shutdown. */ } @@ -149,7 +153,7 @@ namespace winsw { try { - EventLog.WriteEntry(message); + this.EventLog.WriteEntry(message); } catch (Exception e) { @@ -160,7 +164,7 @@ namespace winsw public void LogEvent(string message, EventLogEntryType type) { - if (_systemShuttingdown) + if (this.systemShuttingdown) { /* NOP - cannot call EventLog because of shutdown. */ } @@ -168,7 +172,7 @@ namespace winsw { try { - EventLog.WriteEntry(message, type); + this.EventLog.WriteEntry(message, type); } catch (Exception e) { @@ -179,7 +183,8 @@ namespace winsw protected override void OnStart(string[] args) { - _envs = _descriptor.EnvironmentVariables; + this.envs = this.descriptor.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 /** @@ -187,17 +192,17 @@ namespace winsw { LogEvent("envar " + key + '=' + _envs[key]); }*/ - HandleFileCopies(); + this.HandleFileCopies(); // handle downloads #if VNEXT - List downloads = _descriptor.Downloads; + List downloads = this.descriptor.Downloads; Task[] tasks = new Task[downloads.Count]; for (int i = 0; i < downloads.Count; i++) { Download download = downloads[i]; string downloadMessage = $"Downloading: {download.From} to {download.To}. failOnError={download.FailOnError.ToString()}"; - LogEvent(downloadMessage); + this.LogEvent(downloadMessage); Log.Info(downloadMessage); tasks[i] = download.PerformAsync(); } @@ -216,7 +221,7 @@ namespace winsw Download download = downloads[i]; string errorMessage = $"Failed to download {download.From} to {download.To}"; AggregateException exception = tasks[i].Exception!; - LogEvent($"{errorMessage}. {exception.Message}"); + this.LogEvent($"{errorMessage}. {exception.Message}"); Log.Error(errorMessage, exception); // TODO: move this code into the download logic @@ -230,10 +235,10 @@ namespace winsw throw new AggregateException(exceptions); } #else - foreach (Download download in _descriptor.Downloads) + foreach (Download download in this.descriptor.Downloads) { string downloadMessage = $"Downloading: {download.From} to {download.To}. failOnError={download.FailOnError.ToString()}"; - LogEvent(downloadMessage); + this.LogEvent(downloadMessage); Log.Info(downloadMessage); try { @@ -242,7 +247,7 @@ namespace winsw catch (Exception e) { string errorMessage = $"Failed to download {download.From} to {download.To}"; - LogEvent($"{errorMessage}. {e.Message}"); + this.LogEvent($"{errorMessage}. {e.Message}"); Log.Error(errorMessage, e); // TODO: move this code into the download logic @@ -256,34 +261,34 @@ namespace winsw } #endif - string? startArguments = _descriptor.StartArguments; + string? startArguments = this.descriptor.StartArguments; if (startArguments is null) { - startArguments = _descriptor.Arguments; + startArguments = this.descriptor.Arguments; } else { - startArguments += " " + _descriptor.Arguments; + startArguments += " " + this.descriptor.Arguments; } - // Converting newlines, line returns, tabs into a single + // Converting newlines, line returns, tabs into a single // space. This allows users to provide multi-line arguments // in the xml for readability. startArguments = Regex.Replace(startArguments, @"\s*[\n\r]+\s*", " "); - LogEvent("Starting " + _descriptor.Executable + ' ' + startArguments); - Log.Info("Starting " + _descriptor.Executable + ' ' + startArguments); + this.LogEvent("Starting " + this.descriptor.Executable + ' ' + startArguments); + Log.Info("Starting " + this.descriptor.Executable + ' ' + startArguments); // Load and start extensions - ExtensionManager.LoadExtensions(); - ExtensionManager.FireOnWrapperStarted(); + this.ExtensionManager.LoadExtensions(); + this.ExtensionManager.FireOnWrapperStarted(); - LogHandler executableLogHandler = CreateExecutableLogHandler(); - StartProcess(_process, startArguments, _descriptor.Executable, executableLogHandler, true); - ExtensionManager.FireOnProcessStarted(_process); + LogHandler executableLogHandler = this.CreateExecutableLogHandler(); + this.StartProcess(this.process, startArguments, this.descriptor.Executable, executableLogHandler, true); + this.ExtensionManager.FireOnProcessStarted(this.process); - _process.StandardInput.Close(); // nothing for you to read! + this.process.StandardInput.Close(); // nothing for you to read! } protected override void OnShutdown() @@ -292,8 +297,8 @@ namespace winsw try { - _systemShuttingdown = true; - StopIt(); + this.systemShuttingdown = true; + this.StopIt(); } catch (Exception ex) { @@ -307,7 +312,7 @@ namespace winsw try { - StopIt(); + this.StopIt(); } catch (Exception ex) { @@ -324,18 +329,18 @@ namespace winsw /// private void StopIt() { - string? stopArguments = _descriptor.StopArguments; - LogEvent("Stopping " + _descriptor.Id); - Log.Info("Stopping " + _descriptor.Id); - _orderlyShutdown = true; + string? stopArguments = this.descriptor.StopArguments; + this.LogEvent("Stopping " + this.descriptor.Id); + Log.Info("Stopping " + this.descriptor.Id); + this.orderlyShutdown = true; if (stopArguments is null) { try { - Log.Debug("ProcessKill " + _process.Id); - ProcessHelper.StopProcessAndChildren(_process.Id, _descriptor.StopTimeout, _descriptor.StopParentProcessFirst); - ExtensionManager.FireOnProcessTerminated(_process); + Log.Debug("ProcessKill " + this.process.Id); + ProcessHelper.StopProcessAndChildren(this.process.Id, this.descriptor.StopTimeout, this.descriptor.StopParentProcessFirst); + this.ExtensionManager.FireOnProcessTerminated(this.process); } catch (InvalidOperationException) { @@ -344,48 +349,48 @@ namespace winsw } else { - SignalShutdownPending(); + this.SignalShutdownPending(); - stopArguments += " " + _descriptor.Arguments; + stopArguments += " " + this.descriptor.Arguments; Process stopProcess = new Process(); - string? executable = _descriptor.StopExecutable; + string? executable = this.descriptor.StopExecutable; - executable ??= _descriptor.Executable; + executable ??= this.descriptor.Executable; // TODO: Redirect logging to Log4Net once https://github.com/kohsuke/winsw/pull/213 is integrated - StartProcess(stopProcess, stopArguments, executable, null, false); + this.StartProcess(stopProcess, stopArguments, executable, null, false); - Log.Debug("WaitForProcessToExit " + _process.Id + "+" + stopProcess.Id); - WaitForProcessToExit(_process); - WaitForProcessToExit(stopProcess); + Log.Debug("WaitForProcessToExit " + this.process.Id + "+" + stopProcess.Id); + this.WaitForProcessToExit(this.process); + this.WaitForProcessToExit(stopProcess); } // Stop extensions - ExtensionManager.FireBeforeWrapperStopped(); + this.ExtensionManager.FireBeforeWrapperStopped(); - if (_systemShuttingdown && _descriptor.BeepOnShutdown) + if (this.systemShuttingdown && this.descriptor.BeepOnShutdown) { Console.Beep(); } - Log.Info("Finished " + _descriptor.Id); + Log.Info("Finished " + this.descriptor.Id); } private void WaitForProcessToExit(Process processoWait) { - SignalShutdownPending(); + this.SignalShutdownPending(); int effectiveProcessWaitSleepTime; - if (_descriptor.SleepTime.TotalMilliseconds > int.MaxValue) + if (this.descriptor.SleepTime.TotalMilliseconds > int.MaxValue) { - Log.Warn("The requested sleep time " + _descriptor.SleepTime.TotalMilliseconds + "is greater that the max value " + + Log.Warn("The requested sleep time " + this.descriptor.SleepTime.TotalMilliseconds + "is greater that the max value " + int.MaxValue + ". The value will be truncated"); effectiveProcessWaitSleepTime = int.MaxValue; } else { - effectiveProcessWaitSleepTime = (int)_descriptor.SleepTime.TotalMilliseconds; + effectiveProcessWaitSleepTime = (int)this.descriptor.SleepTime.TotalMilliseconds; } try @@ -394,7 +399,7 @@ namespace winsw while (!processoWait.WaitForExit(effectiveProcessWaitSleepTime)) { - SignalShutdownPending(); + this.SignalShutdownPending(); // WriteEvent("WaitForProcessToExit [repeat]"); } } @@ -409,27 +414,27 @@ namespace winsw private void SignalShutdownPending() { int effectiveWaitHint; - if (_descriptor.WaitHint.TotalMilliseconds > int.MaxValue) + if (this.descriptor.WaitHint.TotalMilliseconds > int.MaxValue) { - Log.Warn("The requested WaitHint value (" + _descriptor.WaitHint.TotalMilliseconds + " ms) is greater that the max value " + + Log.Warn("The requested WaitHint value (" + this.descriptor.WaitHint.TotalMilliseconds + " ms) is greater that the max value " + int.MaxValue + ". The value will be truncated"); effectiveWaitHint = int.MaxValue; } else { - effectiveWaitHint = (int)_descriptor.WaitHint.TotalMilliseconds; + effectiveWaitHint = (int)this.descriptor.WaitHint.TotalMilliseconds; } - RequestAdditionalTime(effectiveWaitHint); + this.RequestAdditionalTime(effectiveWaitHint); } private void SignalShutdownComplete() { - IntPtr handle = ServiceHandle; - _wrapperServiceStatus.CheckPoint++; + IntPtr handle = this.ServiceHandle; + this.wrapperServiceStatus.CheckPoint++; // WriteEvent("SignalShutdownComplete " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint); - _wrapperServiceStatus.CurrentState = ServiceApis.ServiceState.STOPPED; - ServiceApis.SetServiceStatus(handle, _wrapperServiceStatus); + this.wrapperServiceStatus.CurrentState = ServiceApis.ServiceState.STOPPED; + ServiceApis.SetServiceStatus(handle, this.wrapperServiceStatus); } private void StartProcess(Process processToStart, string arguments, string executable, LogHandler? logHandler, bool redirectStdin) @@ -440,25 +445,28 @@ namespace winsw string msg = processToStart.Id + " - " + processToStart.StartInfo.FileName + " " + processToStart.StartInfo.Arguments; try { - if (_orderlyShutdown) + if (this.orderlyShutdown) { - LogEvent("Child process [" + msg + "] terminated with " + proc.ExitCode, EventLogEntryType.Information); + this.LogEvent("Child process [" + msg + "] terminated with " + proc.ExitCode, EventLogEntryType.Information); } else { - LogEvent("Child process [" + msg + "] finished with " + proc.ExitCode, EventLogEntryType.Warning); + this.LogEvent("Child process [" + msg + "] finished with " + proc.ExitCode, EventLogEntryType.Warning); + // if we finished orderly, report that to SCM. // by not reporting unclean shutdown, we let Windows SCM to decide if it wants to // restart the service automatically if (proc.ExitCode == 0) - SignalShutdownComplete(); + { + this.SignalShutdownComplete(); + } Environment.Exit(proc.ExitCode); } } catch (InvalidOperationException ioe) { - LogEvent("WaitForExit " + ioe.Message); + this.LogEvent("WaitForExit " + ioe.Message); } finally { @@ -471,13 +479,13 @@ namespace winsw processToStart: processToStart, executable: executable, arguments: arguments, - envVars: _envs, - workingDirectory: _descriptor.WorkingDirectory, - priority: _descriptor.Priority, + envVars: this.envs, + workingDirectory: this.descriptor.WorkingDirectory, + priority: this.descriptor.Priority, callback: OnProcessCompleted, logHandler: logHandler, redirectStdin: redirectStdin, - hideWindow: _descriptor.HideWindow); + hideWindow: this.descriptor.HideWindow); } } } diff --git a/src/Core/WinSWCore/Configuration/DefaultSettings.cs b/src/Core/WinSWCore/Configuration/DefaultSettings.cs index 3c7a6f2..845b505 100644 --- a/src/Core/WinSWCore/Configuration/DefaultSettings.cs +++ b/src/Core/WinSWCore/Configuration/DefaultSettings.cs @@ -5,57 +5,82 @@ using System.IO; using System.Xml; using WMI; -namespace winsw.Configuration +namespace WinSW.Configuration { /// - /// Default WinSW settings + /// Default WinSW settings. /// public sealed class DefaultWinSWSettings : IWinSWConfiguration { - public string Id => throw new InvalidOperationException(nameof(Id) + " must be specified."); - public string Caption => throw new InvalidOperationException(nameof(Caption) + " must be specified."); - public string Description => throw new InvalidOperationException(nameof(Description) + " must be specified."); - public string Executable => throw new InvalidOperationException(nameof(Executable) + " must be specified."); + public string Id => throw new InvalidOperationException(nameof(this.Id) + " must be specified."); + + public string Caption => throw new InvalidOperationException(nameof(this.Caption) + " must be specified."); + + public string Description => throw new InvalidOperationException(nameof(this.Description) + " must be specified."); + + 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? ServiceAccountUser => 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(ExecutablePath)!; + + public string WorkingDirectory => Path.GetDirectoryName(this.ExecutablePath)!; + public ProcessPriorityClass Priority => ProcessPriorityClass.Normal; + public TimeSpan StopTimeout => TimeSpan.FromSeconds(15); + public bool StopParentProcessFirst => false; // Service management public StartMode StartMode => StartMode.Automatic; + public bool DelayedAutoStart => false; + public string[] ServiceDependencies => new string[0]; + public TimeSpan WaitHint => TimeSpan.FromSeconds(15); + public TimeSpan SleepTime => TimeSpan.FromSeconds(1); + public bool Interactive => false; // Logging - public string LogDirectory => Path.GetDirectoryName(ExecutablePath)!; + 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 diff --git a/src/Core/WinSWCore/Configuration/IWinSWConfiguration.cs b/src/Core/WinSWCore/Configuration/IWinSWConfiguration.cs index be9f56b..0cd85ee 100644 --- a/src/Core/WinSWCore/Configuration/IWinSWConfiguration.cs +++ b/src/Core/WinSWCore/Configuration/IWinSWConfiguration.cs @@ -4,50 +4,71 @@ using System.Diagnostics; using System.Xml; using WMI; -namespace winsw.Configuration +namespace WinSW.Configuration { public interface IWinSWConfiguration { // TODO: Document the parameters && refactor - 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? ServiceAccountUser { 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; } + bool StopParentProcessFirst { get; } // Service management StartMode StartMode { get; } + string[] ServiceDependencies { get; } + TimeSpan WaitHint { get; } + TimeSpan SleepTime { get; } + bool Interactive { get; } // Logging string LogDirectory { get; } + // TODO: replace by enum string LogMode { get; } // Environment List Downloads { get; } + Dictionary EnvironmentVariables { get; } // Misc diff --git a/src/Core/WinSWCore/Download.cs b/src/Core/WinSWCore/Download.cs index f0d2c22..dc70b2f 100755 --- a/src/Core/WinSWCore/Download.cs +++ b/src/Core/WinSWCore/Download.cs @@ -10,9 +10,9 @@ using System.Threading.Tasks; #endif using System.Xml; using log4net; -using winsw.Util; +using WinSW.Util; -namespace winsw +namespace WinSW { /// /// Specify the download activities prior to the launch. @@ -22,9 +22,9 @@ namespace winsw { public enum AuthType { - none = 0, - sspi, - basic + None = 0, + Sspi, + Basic } private static readonly ILog Logger = LogManager.GetLogger(typeof(Download)); @@ -38,7 +38,7 @@ namespace winsw public readonly bool FailOnError; public readonly string? Proxy; - public string ShortId => $"(download from {From})"; + public string ShortId => $"(download from {this.From})"; static Download() { @@ -73,59 +73,59 @@ namespace winsw string from, string to, bool failOnError = false, - AuthType auth = AuthType.none, + AuthType auth = AuthType.None, string? username = null, string? password = null, bool unsecureAuth = false, string? proxy = null) { - From = from; - To = to; - FailOnError = failOnError; - Proxy = proxy; - Auth = auth; - Username = username; - Password = password; - UnsecureAuth = unsecureAuth; + this.From = from; + this.To = to; + this.FailOnError = failOnError; + this.Proxy = proxy; + this.Auth = auth; + this.Username = username; + this.Password = password; + this.UnsecureAuth = unsecureAuth; } /// /// Constructs the download setting sfrom the XML entry /// /// XML element - /// The required attribute is missing or the configuration is invalid + /// The required attribute is missing or the configuration is invalid. internal Download(XmlElement n) { - From = XmlHelper.SingleAttribute(n, "from"); - To = XmlHelper.SingleAttribute(n, "to"); + this.From = XmlHelper.SingleAttribute(n, "from"); + this.To = XmlHelper.SingleAttribute(n, "to"); // All arguments below are optional - FailOnError = XmlHelper.SingleAttribute(n, "failOnError", false); - Proxy = XmlHelper.SingleAttribute(n, "proxy", null); + this.FailOnError = XmlHelper.SingleAttribute(n, "failOnError", false); + this.Proxy = XmlHelper.SingleAttribute(n, "proxy", null); - Auth = XmlHelper.EnumAttribute(n, "auth", AuthType.none); - Username = XmlHelper.SingleAttribute(n, "user", null); - Password = XmlHelper.SingleAttribute(n, "password", null); - UnsecureAuth = XmlHelper.SingleAttribute(n, "unsecureAuth", false); + this.Auth = XmlHelper.EnumAttribute(n, "auth", AuthType.None); + this.Username = XmlHelper.SingleAttribute(n, "user", null); + this.Password = XmlHelper.SingleAttribute(n, "password", null); + this.UnsecureAuth = XmlHelper.SingleAttribute(n, "unsecureAuth", false); - if (Auth == AuthType.basic) + if (this.Auth == AuthType.Basic) { // Allow it only for HTTPS or for UnsecureAuth - if (!From.StartsWith("https:") && !UnsecureAuth) + if (!this.From.StartsWith("https:") && !this.UnsecureAuth) { - throw new InvalidDataException("Warning: you're sending your credentials in clear text to the server " + ShortId + + throw new InvalidDataException("Warning: you're sending your credentials in clear text to the server " + this.ShortId + "If you really want this you must enable 'unsecureAuth' in the configuration"); } // Also fail if there is no user/password - if (Username is null) + if (this.Username is null) { - throw new InvalidDataException("Basic Auth is enabled, but username is not specified " + ShortId); + throw new InvalidDataException("Basic Auth is enabled, but username is not specified " + this.ShortId); } - if (Password is null) + if (this.Password is null) { - throw new InvalidDataException("Basic Auth is enabled, but password is not specified " + ShortId); + throw new InvalidDataException("Basic Auth is enabled, but password is not specified " + this.ShortId); } } } @@ -150,10 +150,10 @@ namespace winsw public void Perform() #endif { - WebRequest request = WebRequest.Create(From); - if (!string.IsNullOrEmpty(Proxy)) + WebRequest request = WebRequest.Create(this.From); + if (!string.IsNullOrEmpty(this.Proxy)) { - CustomProxyInformation proxyInformation = new CustomProxyInformation(Proxy); + CustomProxyInformation proxyInformation = new CustomProxyInformation(this.Proxy!); if (proxyInformation.Credentials != null) { request.Proxy = new WebProxy(proxyInformation.ServerAddress, false, null, proxyInformation.Credentials); @@ -164,35 +164,35 @@ namespace winsw } } - switch (Auth) + switch (this.Auth) { - case AuthType.none: + case AuthType.None: // Do nothing break; - case AuthType.sspi: + case AuthType.Sspi: request.UseDefaultCredentials = true; request.PreAuthenticate = true; request.Credentials = CredentialCache.DefaultCredentials; break; - case AuthType.basic: - SetBasicAuthHeader(request, Username!, Password!); + case AuthType.Basic: + this.SetBasicAuthHeader(request, this.Username!, this.Password!); break; default: - throw new WebException("Code defect. Unsupported authentication type: " + Auth); + throw new WebException("Code defect. Unsupported authentication type: " + this.Auth); } bool supportsIfModifiedSince = false; - if (request is HttpWebRequest httpRequest && File.Exists(To)) + if (request is HttpWebRequest httpRequest && File.Exists(this.To)) { supportsIfModifiedSince = true; - httpRequest.IfModifiedSince = File.GetLastWriteTime(To); + httpRequest.IfModifiedSince = File.GetLastWriteTime(this.To); } DateTime lastModified = default; - string tmpFilePath = To + ".tmp"; + string tmpFilePath = this.To + ".tmp"; try { #if VNEXT @@ -217,18 +217,18 @@ namespace winsw #endif } - FileHelper.MoveOrReplaceFile(To + ".tmp", To); + FileHelper.MoveOrReplaceFile(this.To + ".tmp", this.To); if (supportsIfModifiedSince) { - File.SetLastWriteTime(To, lastModified); + File.SetLastWriteTime(this.To, lastModified); } } catch (WebException e) { if (supportsIfModifiedSince && ((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.NotModified) { - Logger.Info($"Skipped downloading unmodified resource '{From}'"); + Logger.Info($"Skipped downloading unmodified resource '{this.From}'"); } else { @@ -253,6 +253,7 @@ namespace winsw public class CustomProxyInformation { public string ServerAddress { get; set; } + public NetworkCredential? Credentials { get; set; } public CustomProxyInformation(string proxy) @@ -267,12 +268,12 @@ namespace winsw string username = completeCredsStr.Substring(0, credsSeparator); string password = completeCredsStr.Substring(credsSeparator + 1); - Credentials = new NetworkCredential(username, password); - ServerAddress = proxy.Replace(completeCredsStr + "@", ""); + this.Credentials = new NetworkCredential(username, password); + this.ServerAddress = proxy.Replace(completeCredsStr + "@", string.Empty); } else { - ServerAddress = proxy; + this.ServerAddress = proxy; } } } diff --git a/src/Core/WinSWCore/DynamicProxy.cs b/src/Core/WinSWCore/DynamicProxy.cs index 0589e27..d1ba71a 100644 --- a/src/Core/WinSWCore/DynamicProxy.cs +++ b/src/Core/WinSWCore/DynamicProxy.cs @@ -80,14 +80,19 @@ namespace DynamicProxy // Load "this" constructorIL.Emit(OpCodes.Ldarg_0); + // Load first constructor parameter constructorIL.Emit(OpCodes.Ldarg_1); + // Set the first parameter into the handler field constructorIL.Emit(OpCodes.Stfld, handlerField); + // Load "this" constructorIL.Emit(OpCodes.Ldarg_0); + // Call the super constructor constructorIL.Emit(OpCodes.Call, baseConstructor); + // Constructor return constructorIL.Emit(OpCodes.Ret); @@ -136,7 +141,8 @@ namespace DynamicProxy methodInfo.Name, /*MethodAttributes.Public | MethodAttributes.Virtual | */ methodInfo.Attributes & ~MethodAttributes.Abstract, CallingConventions.Standard, - methodInfo.ReturnType, methodParameters); + methodInfo.ReturnType, + methodParameters); ILGenerator methodIL = methodBuilder.GetILGenerator(); diff --git a/src/Core/WinSWCore/Extensions/AbstractWinSWExtension.cs b/src/Core/WinSWCore/Extensions/AbstractWinSWExtension.cs index 5173e84..bfc5f4a 100644 --- a/src/Core/WinSWCore/Extensions/AbstractWinSWExtension.cs +++ b/src/Core/WinSWCore/Extensions/AbstractWinSWExtension.cs @@ -1,6 +1,6 @@ using System.Xml; -namespace winsw.Extensions +namespace WinSW.Extensions { public abstract class AbstractWinSWExtension : IWinSWExtension { diff --git a/src/Core/WinSWCore/Extensions/ExtensionException.cs b/src/Core/WinSWCore/Extensions/ExtensionException.cs index 48a5ae2..87d4417 100644 --- a/src/Core/WinSWCore/Extensions/ExtensionException.cs +++ b/src/Core/WinSWCore/Extensions/ExtensionException.cs @@ -1,6 +1,6 @@ using System; -namespace winsw.Extensions +namespace WinSW.Extensions { public class ExtensionException : WinSWException { @@ -9,15 +9,15 @@ namespace winsw.Extensions public ExtensionException(string extensionName, string message) : base(message) { - ExtensionId = extensionName; + this.ExtensionId = extensionName; } public ExtensionException(string extensionName, string message, Exception innerException) : base(message, innerException) { - ExtensionId = extensionName; + this.ExtensionId = extensionName; } - public override string Message => ExtensionId + ": " + base.Message; + public override string Message => this.ExtensionId + ": " + base.Message; } } diff --git a/src/Core/WinSWCore/Extensions/ExtensionPointAttribute.cs b/src/Core/WinSWCore/Extensions/ExtensionPointAttribute.cs index fd51b4d..5f65a15 100644 --- a/src/Core/WinSWCore/Extensions/ExtensionPointAttribute.cs +++ b/src/Core/WinSWCore/Extensions/ExtensionPointAttribute.cs @@ -1,4 +1,4 @@ -namespace winsw.Extensions +namespace WinSW.Extensions { /// /// This attribute is used to identify extension points within the code @@ -6,7 +6,7 @@ /// /// Each extension point implements its own entry type. /// - class ExtensionPointAttribute + internal class ExtensionPointAttribute { } } diff --git a/src/Core/WinSWCore/Extensions/IWinSWExtension.cs b/src/Core/WinSWCore/Extensions/IWinSWExtension.cs index e10819a..a7c1f35 100644 --- a/src/Core/WinSWCore/Extensions/IWinSWExtension.cs +++ b/src/Core/WinSWCore/Extensions/IWinSWExtension.cs @@ -1,6 +1,6 @@ using System.Xml; -namespace winsw.Extensions +namespace WinSW.Extensions { /// /// Interface for Win Service Wrapper Extension diff --git a/src/Core/WinSWCore/Extensions/WinSWExtensionDescriptor.cs b/src/Core/WinSWCore/Extensions/WinSWExtensionDescriptor.cs index 60fe91a..e8794f1 100644 --- a/src/Core/WinSWCore/Extensions/WinSWExtensionDescriptor.cs +++ b/src/Core/WinSWCore/Extensions/WinSWExtensionDescriptor.cs @@ -1,7 +1,7 @@ using System.Xml; -using winsw.Util; +using WinSW.Util; -namespace winsw.Extensions +namespace WinSW.Extensions { /// /// Describes WinSW extensions in @@ -28,9 +28,9 @@ namespace winsw.Extensions private WinSWExtensionDescriptor(string id, string className, bool enabled) { - Id = id; - Enabled = enabled; - ClassName = className; + this.Id = id; + this.Enabled = enabled; + this.ClassName = className; } public static WinSWExtensionDescriptor FromXml(XmlElement node) diff --git a/src/Core/WinSWCore/Extensions/WinSWExtensionManager.cs b/src/Core/WinSWCore/Extensions/WinSWExtensionManager.cs index d182875..081658c 100644 --- a/src/Core/WinSWCore/Extensions/WinSWExtensionManager.cs +++ b/src/Core/WinSWCore/Extensions/WinSWExtensionManager.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Xml; using log4net; -namespace winsw.Extensions +namespace WinSW.Extensions { public class WinSWExtensionManager { @@ -15,8 +15,8 @@ namespace winsw.Extensions public WinSWExtensionManager(ServiceDescriptor serviceDescriptor) { - ServiceDescriptor = serviceDescriptor; - Extensions = new Dictionary(); + this.ServiceDescriptor = serviceDescriptor; + this.Extensions = new Dictionary(); } /// @@ -27,7 +27,7 @@ namespace winsw.Extensions /// Start failure public void FireOnWrapperStarted() { - foreach (var ext in Extensions) + foreach (var ext in this.Extensions) { try { @@ -47,7 +47,7 @@ namespace winsw.Extensions /// public void FireBeforeWrapperStopped() { - foreach (var ext in Extensions) + foreach (var ext in this.Extensions) { try { @@ -66,7 +66,7 @@ namespace winsw.Extensions /// Process public void FireOnProcessStarted(System.Diagnostics.Process process) { - foreach (var ext in Extensions) + foreach (var ext in this.Extensions) { try { @@ -85,7 +85,7 @@ namespace winsw.Extensions /// Process public void FireOnProcessTerminated(System.Diagnostics.Process process) { - foreach (var ext in Extensions) + foreach (var ext in this.Extensions) { try { @@ -101,16 +101,16 @@ namespace winsw.Extensions // TODO: Implement loading of external extensions. Current version supports internal hack #region Extension load management + /// /// Loads extensions according to the configuration file. /// - /// Logger /// Loading failure public void LoadExtensions() { - var extensionIds = ServiceDescriptor.ExtensionIds; + var extensionIds = this.ServiceDescriptor.ExtensionIds; foreach (string extensionId in extensionIds) { - LoadExtension(extensionId); + this.LoadExtension(extensionId); } } @@ -118,16 +118,15 @@ namespace winsw.Extensions /// Loads extensions from the configuration file /// /// Extension ID - /// Logger /// Loading failure private void LoadExtension(string id) { - if (Extensions.ContainsKey(id)) + if (this.Extensions.ContainsKey(id)) { throw new ExtensionException(id, "Extension has been already loaded"); } - XmlNode? extensionsConfig = ServiceDescriptor.ExtensionsConfiguration; + XmlNode? extensionsConfig = this.ServiceDescriptor.ExtensionsConfiguration; XmlElement? configNode = extensionsConfig is null ? null : extensionsConfig.SelectSingleNode("extension[@id='" + id + "'][1]") as XmlElement; if (configNode is null) { @@ -137,11 +136,11 @@ namespace winsw.Extensions var descriptor = WinSWExtensionDescriptor.FromXml(configNode); if (descriptor.Enabled) { - IWinSWExtension extension = CreateExtensionInstance(descriptor.Id, descriptor.ClassName); + IWinSWExtension extension = this.CreateExtensionInstance(descriptor.Id, descriptor.ClassName); extension.Descriptor = descriptor; try { - extension.Configure(ServiceDescriptor, configNode); + extension.Configure(this.ServiceDescriptor, configNode); } catch (Exception ex) { // Consider any unexpected exception as fatal @@ -149,7 +148,7 @@ namespace winsw.Extensions throw ex; } - Extensions.Add(id, extension); + this.Extensions.Add(id, extension); Log.Info("Extension loaded: " + id); } else diff --git a/src/Core/WinSWCore/LogAppenders.cs b/src/Core/WinSWCore/LogAppenders.cs index 855c4a1..564a58d 100644 --- a/src/Core/WinSWCore/LogAppenders.cs +++ b/src/Core/WinSWCore/LogAppenders.cs @@ -8,12 +8,11 @@ using System.Threading; #if !VNEXT using ICSharpCode.SharpZipLib.Zip; #endif -using winsw.Util; +using WinSW.Util; -namespace winsw +namespace WinSW { - // ReSharper disable once InconsistentNaming - public interface EventLogger + public interface IEventLogger { void LogEvent(string message); @@ -25,14 +24,13 @@ namespace winsw /// public abstract class LogHandler { - // ReSharper disable once InconsistentNaming - public abstract void log(StreamReader outputReader, StreamReader errorReader); + public abstract void Log(StreamReader outputReader, StreamReader errorReader); /// /// Error and information about logging should be reported here. /// #pragma warning disable CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. - public EventLogger EventLogger { get; set; } + public IEventLogger EventLogger { get; set; } #pragma warning restore CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. /// @@ -61,7 +59,7 @@ namespace winsw } catch (IOException e) { - EventLogger.LogEvent("Failed to move :" + sourceFileName + " to " + destFileName + " because " + e.Message); + this.EventLogger.LogEvent("Failed to move :" + sourceFileName + " to " + destFileName + " because " + e.Message); } } } @@ -72,21 +70,25 @@ namespace winsw public abstract class AbstractFileLogAppender : LogHandler { protected string BaseLogFileName { get; private set; } + protected bool OutFileDisabled { get; private set; } + protected bool ErrFileDisabled { get; private set; } + protected string OutFilePattern { get; private set; } + protected string ErrFilePattern { get; private set; } protected AbstractFileLogAppender(string logDirectory, string baseName, bool outFileDisabled, bool errFileDisabled, string outFilePattern, string errFilePattern) { - BaseLogFileName = Path.Combine(logDirectory, baseName); - OutFileDisabled = outFileDisabled; - OutFilePattern = outFilePattern; - ErrFileDisabled = errFileDisabled; - ErrFilePattern = errFilePattern; + this.BaseLogFileName = Path.Combine(logDirectory, baseName); + this.OutFileDisabled = outFileDisabled; + this.OutFilePattern = outFilePattern; + this.ErrFileDisabled = errFileDisabled; + this.ErrFilePattern = errFilePattern; } - public override void log(StreamReader outputReader, StreamReader errorReader) + public override void Log(StreamReader outputReader, StreamReader errorReader) { if (this.OutFileDisabled) { @@ -117,25 +119,27 @@ namespace winsw public abstract class SimpleLogAppender : AbstractFileLogAppender { public FileMode FileMode { get; private set; } + public string OutputLogFileName { get; private set; } + public string ErrorLogFileName { get; private set; } protected SimpleLogAppender(string logDirectory, string baseName, FileMode fileMode, bool outFileDisabled, bool errFileDisabled, string outFilePattern, string errFilePattern) : base(logDirectory, baseName, outFileDisabled, errFileDisabled, outFilePattern, errFilePattern) { - FileMode = fileMode; - OutputLogFileName = BaseLogFileName + ".out.log"; - ErrorLogFileName = BaseLogFileName + ".err.log"; + this.FileMode = fileMode; + this.OutputLogFileName = this.BaseLogFileName + ".out.log"; + this.ErrorLogFileName = this.BaseLogFileName + ".err.log"; } protected override void LogOutput(StreamReader outputReader) { - new Thread(() => CopyStream(outputReader, CreateWriter(new FileStream(OutputLogFileName, FileMode)))).Start(); + new Thread(() => this.CopyStream(outputReader, this.CreateWriter(new FileStream(this.OutputLogFileName, this.FileMode)))).Start(); } protected override void LogError(StreamReader errorReader) { - new Thread(() => CopyStream(errorReader, CreateWriter(new FileStream(ErrorLogFileName, FileMode)))).Start(); + new Thread(() => this.CopyStream(errorReader, this.CreateWriter(new FileStream(this.ErrorLogFileName, this.FileMode)))).Start(); } } @@ -160,7 +164,7 @@ namespace winsw /// public class IgnoreLogAppender : LogHandler { - public override void log(StreamReader outputReader, StreamReader errorReader) + public override void Log(StreamReader outputReader, StreamReader errorReader) { outputReader.Dispose(); errorReader.Dispose(); @@ -170,23 +174,24 @@ namespace winsw public class TimeBasedRollingLogAppender : AbstractFileLogAppender { public string Pattern { get; private set; } + public int Period { get; private set; } public TimeBasedRollingLogAppender(string logDirectory, string baseName, bool outFileDisabled, bool errFileDisabled, string outFilePattern, string errFilePattern, string pattern, int period) : base(logDirectory, baseName, outFileDisabled, errFileDisabled, outFilePattern, errFilePattern) { - Pattern = pattern; - Period = period; + this.Pattern = pattern; + this.Period = period; } protected override void LogOutput(StreamReader outputReader) { - new Thread(() => CopyStreamWithDateRotation(outputReader, OutFilePattern)).Start(); + new Thread(() => this.CopyStreamWithDateRotation(outputReader, this.OutFilePattern)).Start(); } protected override void LogError(StreamReader errorReader) { - new Thread(() => CopyStreamWithDateRotation(errorReader, ErrFilePattern)).Start(); + new Thread(() => this.CopyStreamWithDateRotation(errorReader, this.ErrFilePattern)).Start(); } /// @@ -194,17 +199,17 @@ namespace winsw /// private void CopyStreamWithDateRotation(StreamReader reader, string ext) { - PeriodicRollingCalendar periodicRollingCalendar = new PeriodicRollingCalendar(Pattern, Period); - periodicRollingCalendar.init(); + PeriodicRollingCalendar periodicRollingCalendar = new PeriodicRollingCalendar(this.Pattern, this.Period); + periodicRollingCalendar.Init(); - StreamWriter writer = CreateWriter(new FileStream(BaseLogFileName + "_" + periodicRollingCalendar.format + ext, FileMode.Append)); + StreamWriter writer = this.CreateWriter(new FileStream(this.BaseLogFileName + "_" + periodicRollingCalendar.Format + ext, FileMode.Append)); string? line; while ((line = reader.ReadLine()) != null) { - if (periodicRollingCalendar.shouldRoll) + if (periodicRollingCalendar.ShouldRoll) { writer.Dispose(); - writer = CreateWriter(new FileStream(BaseLogFileName + "_" + periodicRollingCalendar.format + ext, FileMode.Create)); + writer = this.CreateWriter(new FileStream(this.BaseLogFileName + "_" + periodicRollingCalendar.Format + ext, FileMode.Create)); } writer.WriteLine(line); @@ -217,14 +222,10 @@ namespace winsw public class SizeBasedRollingLogAppender : AbstractFileLogAppender { - // ReSharper disable once InconsistentNaming - public static int BYTES_PER_KB = 1024; - // ReSharper disable once InconsistentNaming - public static int BYTES_PER_MB = 1024 * BYTES_PER_KB; - // ReSharper disable once InconsistentNaming - public static int DEFAULT_SIZE_THRESHOLD = 10 * BYTES_PER_MB; // roll every 10MB. - // ReSharper disable once InconsistentNaming - public static int DEFAULT_FILES_TO_KEEP = 8; + public static int BytesPerKB = 1024; + public static int BytesPerMB = 1024 * BytesPerKB; + public static int DefaultSizeThreshold = 10 * BytesPerMB; // roll every 10MB. + public static int DefaultFilesToKeep = 8; public int SizeTheshold { get; private set; } @@ -233,21 +234,23 @@ namespace winsw public SizeBasedRollingLogAppender(string logDirectory, string baseName, bool outFileDisabled, bool errFileDisabled, string outFilePattern, string errFilePattern, int sizeThreshold, int filesToKeep) : base(logDirectory, baseName, outFileDisabled, errFileDisabled, outFilePattern, errFilePattern) { - SizeTheshold = sizeThreshold; - FilesToKeep = filesToKeep; + this.SizeTheshold = sizeThreshold; + this.FilesToKeep = filesToKeep; } public SizeBasedRollingLogAppender(string logDirectory, string baseName, bool outFileDisabled, bool errFileDisabled, string outFilePattern, string errFilePattern) - : this(logDirectory, baseName, outFileDisabled, errFileDisabled, outFilePattern, errFilePattern, DEFAULT_SIZE_THRESHOLD, DEFAULT_FILES_TO_KEEP) { } + : this(logDirectory, baseName, outFileDisabled, errFileDisabled, outFilePattern, errFilePattern, DefaultSizeThreshold, DefaultFilesToKeep) + { + } protected override void LogOutput(StreamReader outputReader) { - new Thread(() => CopyStreamWithRotation(outputReader, OutFilePattern)).Start(); + new Thread(() => this.CopyStreamWithRotation(outputReader, this.OutFilePattern)).Start(); } protected override void LogError(StreamReader errorReader) { - new Thread(() => CopyStreamWithRotation(errorReader, ErrFilePattern)).Start(); + new Thread(() => this.CopyStreamWithRotation(errorReader, this.ErrFilePattern)).Start(); } /// @@ -255,41 +258,45 @@ namespace winsw /// private void CopyStreamWithRotation(StreamReader reader, string ext) { - StreamWriter writer = CreateWriter(new FileStream(BaseLogFileName + ext, FileMode.Append)); - long fileLength = new FileInfo(BaseLogFileName + ext).Length; + StreamWriter writer = this.CreateWriter(new FileStream(this.BaseLogFileName + ext, FileMode.Append)); + long fileLength = new FileInfo(this.BaseLogFileName + ext).Length; string? line; while ((line = reader.ReadLine()) != null) { int lengthToWrite = (line.Length + Environment.NewLine.Length) * sizeof(char); - if (fileLength + lengthToWrite > SizeTheshold) + if (fileLength + lengthToWrite > this.SizeTheshold) { writer.Dispose(); try { - for (int j = FilesToKeep; j >= 1; j--) + for (int j = this.FilesToKeep; j >= 1; j--) { - string dst = BaseLogFileName + "." + (j - 1) + ext; - string src = BaseLogFileName + "." + (j - 2) + ext; + string dst = this.BaseLogFileName + "." + (j - 1) + ext; + string src = this.BaseLogFileName + "." + (j - 2) + ext; if (File.Exists(dst)) + { File.Delete(dst); + } if (File.Exists(src)) + { File.Move(src, dst); + } } - File.Move(BaseLogFileName + ext, BaseLogFileName + ".0" + ext); + File.Move(this.BaseLogFileName + ext, this.BaseLogFileName + ".0" + ext); } catch (IOException e) { - EventLogger.LogEvent("Failed to roll log: " + e.Message); + this.EventLogger.LogEvent("Failed to roll log: " + e.Message); } // even if the log rotation fails, create a new one, or else // we'll infinitely try to roll. - writer = CreateWriter(new FileStream(BaseLogFileName + ext, FileMode.Create)); - fileLength = new FileInfo(BaseLogFileName + ext).Length; + writer = this.CreateWriter(new FileStream(this.BaseLogFileName + ext, FileMode.Create)); + fileLength = new FileInfo(this.BaseLogFileName + ext).Length; } writer.WriteLine(line); @@ -311,25 +318,34 @@ namespace winsw { } - public override void log(StreamReader outputReader, StreamReader errorReader) + public override void Log(StreamReader outputReader, StreamReader errorReader) { - if (!OutFileDisabled) - MoveFile(OutputLogFileName, OutputLogFileName + ".old"); + if (!this.OutFileDisabled) + { + this.MoveFile(this.OutputLogFileName, this.OutputLogFileName + ".old"); + } - if (!ErrFileDisabled) - MoveFile(ErrorLogFileName, ErrorLogFileName + ".old"); + if (!this.ErrFileDisabled) + { + this.MoveFile(this.ErrorLogFileName, this.ErrorLogFileName + ".old"); + } - base.log(outputReader, errorReader); + base.Log(outputReader, errorReader); } } public class RollingSizeTimeLogAppender : AbstractFileLogAppender { - public static int BYTES_PER_KB = 1024; + public static int BytesPerKB = 1024; + public int SizeTheshold { get; private set; } + public string FilePattern { get; private set; } + public TimeSpan? AutoRollAtTime { get; private set; } + public int? ZipOlderThanNumDays { get; private set; } + public string ZipDateFormat { get; private set; } public RollingSizeTimeLogAppender( @@ -346,21 +362,21 @@ namespace winsw string zipdateformat) : base(logDirectory, baseName, outFileDisabled, errFileDisabled, outFilePattern, errFilePattern) { - SizeTheshold = sizeThreshold; - FilePattern = filePattern; - AutoRollAtTime = autoRollAtTime; - ZipOlderThanNumDays = zipolderthannumdays; - ZipDateFormat = zipdateformat; + this.SizeTheshold = sizeThreshold; + this.FilePattern = filePattern; + this.AutoRollAtTime = autoRollAtTime; + this.ZipOlderThanNumDays = zipolderthannumdays; + this.ZipDateFormat = zipdateformat; } protected override void LogOutput(StreamReader outputReader) { - new Thread(() => CopyStreamWithRotation(outputReader, OutFilePattern)).Start(); + new Thread(() => this.CopyStreamWithRotation(outputReader, this.OutFilePattern)).Start(); } protected override void LogError(StreamReader errorReader) { - new Thread(() => CopyStreamWithRotation(errorReader, ErrFilePattern)).Start(); + new Thread(() => this.CopyStreamWithRotation(errorReader, this.ErrFilePattern)).Start(); } private void CopyStreamWithRotation(StreamReader reader, string extension) @@ -368,18 +384,18 @@ namespace winsw // lock required as the timer thread and the thread that will write to the stream could try and access the file stream at the same time var fileLock = new object(); - var baseDirectory = Path.GetDirectoryName(BaseLogFileName)!; - var baseFileName = Path.GetFileName(BaseLogFileName); - var logFile = BaseLogFileName + extension; + var baseDirectory = Path.GetDirectoryName(this.BaseLogFileName)!; + var baseFileName = Path.GetFileName(this.BaseLogFileName); + var logFile = this.BaseLogFileName + extension; - var writer = CreateWriter(new FileStream(logFile, FileMode.Append)); + var writer = this.CreateWriter(new FileStream(logFile, FileMode.Append)); var fileLength = new FileInfo(logFile).Length; // We auto roll at time is configured then we need to create a timer and wait until time is elasped and roll the file over - if (AutoRollAtTime is TimeSpan autoRollAtTime) + if (this.AutoRollAtTime is TimeSpan autoRollAtTime) { // Run at start - var tickTime = SetupRollTimer(autoRollAtTime); + var tickTime = this.SetupRollTimer(autoRollAtTime); var timer = new System.Timers.Timer(tickTime); timer.Elapsed += (s, e) => { @@ -391,25 +407,25 @@ namespace winsw writer.Dispose(); var now = DateTime.Now.AddDays(-1); - var nextFileNumber = GetNextFileNumber(extension, baseDirectory, baseFileName, now); - var nextFileName = Path.Combine(baseDirectory, string.Format("{0}.{1}.#{2:D4}{3}", baseFileName, now.ToString(FilePattern), nextFileNumber, extension)); + var nextFileNumber = this.GetNextFileNumber(extension, baseDirectory, baseFileName, now); + var nextFileName = Path.Combine(baseDirectory, string.Format("{0}.{1}.#{2:D4}{3}", baseFileName, now.ToString(this.FilePattern), nextFileNumber, extension)); File.Move(logFile, nextFileName); - writer = CreateWriter(new FileStream(logFile, FileMode.Create)); + writer = this.CreateWriter(new FileStream(logFile, FileMode.Create)); fileLength = new FileInfo(logFile).Length; } // Next day so check if file can be zipped - ZipFiles(baseDirectory, extension, baseFileName); + this.ZipFiles(baseDirectory, extension, baseFileName); } catch (Exception ex) { - EventLogger.LogEvent($"Failed to to trigger auto roll at time event due to: {ex.Message}"); + this.EventLogger.LogEvent($"Failed to to trigger auto roll at time event due to: {ex.Message}"); } finally { // Recalculate the next interval - timer.Interval = SetupRollTimer(autoRollAtTime); + timer.Interval = this.SetupRollTimer(autoRollAtTime); timer.Start(); } }; @@ -422,26 +438,26 @@ namespace winsw lock (fileLock) { int lengthToWrite = (line.Length + Environment.NewLine.Length) * sizeof(char); - if (fileLength + lengthToWrite > SizeTheshold) + if (fileLength + lengthToWrite > this.SizeTheshold) { try { // roll file var now = DateTime.Now; - var nextFileNumber = GetNextFileNumber(extension, baseDirectory, baseFileName, now); - var nextFileName = - Path.Combine(baseDirectory, - string.Format("{0}.{1}.#{2:D4}{3}", baseFileName, now.ToString(FilePattern), nextFileNumber, extension)); + var nextFileNumber = this.GetNextFileNumber(extension, baseDirectory, baseFileName, now); + var nextFileName = Path.Combine( + baseDirectory, + string.Format("{0}.{1}.#{2:D4}{3}", baseFileName, now.ToString(this.FilePattern), nextFileNumber, extension)); File.Move(logFile, nextFileName); // even if the log rotation fails, create a new one, or else // we'll infinitely try to roll. - writer = CreateWriter(new FileStream(logFile, FileMode.Create)); + writer = this.CreateWriter(new FileStream(logFile, FileMode.Create)); fileLength = new FileInfo(logFile).Length; } catch (Exception e) { - EventLogger.LogEvent($"Failed to roll size time log: {e.Message}"); + this.EventLogger.LogEvent($"Failed to roll size time log: {e.Message}"); } } @@ -456,28 +472,32 @@ namespace winsw private void ZipFiles(string directory, string fileExtension, string zipFileBaseName) { - if (ZipOlderThanNumDays is null || ZipOlderThanNumDays <= 0) + if (this.ZipOlderThanNumDays is null || this.ZipOlderThanNumDays <= 0) + { return; + } try { foreach (string path in Directory.GetFiles(directory, "*" + fileExtension)) { var fileInfo = new FileInfo(path); - if (fileInfo.LastWriteTimeUtc >= DateTime.UtcNow.AddDays(-ZipOlderThanNumDays.Value)) + if (fileInfo.LastWriteTimeUtc >= DateTime.UtcNow.AddDays(-this.ZipOlderThanNumDays.Value)) + { continue; + } string sourceFileName = Path.GetFileName(path); - string zipFilePattern = fileInfo.LastAccessTimeUtc.ToString(ZipDateFormat); + string zipFilePattern = fileInfo.LastAccessTimeUtc.ToString(this.ZipDateFormat); string zipFilePath = Path.Combine(directory, $"{zipFileBaseName}.{zipFilePattern}.zip"); - ZipOneFile(path, sourceFileName, zipFilePath); + this.ZipOneFile(path, sourceFileName, zipFilePath); File.Delete(path); } } catch (Exception e) { - EventLogger.LogEvent($"Failed to Zip files. Error {e.Message}"); + this.EventLogger.LogEvent($"Failed to Zip files. Error {e.Message}"); } } @@ -496,7 +516,7 @@ namespace winsw } catch (Exception e) { - EventLogger.LogEvent($"Failed to Zip the File {sourceFilePath}. Error {e.Message}"); + this.EventLogger.LogEvent($"Failed to Zip the File {sourceFilePath}. Error {e.Message}"); } finally { @@ -521,7 +541,7 @@ namespace winsw } catch (Exception e) { - EventLogger.LogEvent($"Failed to Zip the File {sourceFilePath}. Error {e.Message}"); + this.EventLogger.LogEvent($"Failed to Zip the File {sourceFilePath}. Error {e.Message}"); zipFile?.AbortUpdate(); } finally @@ -543,7 +563,9 @@ namespace winsw autoRollAtTime.Seconds, 0); if (nowTime > scheduledTime) + { scheduledTime = scheduledTime.AddDays(1); + } double tickTime = (scheduledTime - DateTime.Now).TotalMilliseconds; return tickTime; @@ -552,7 +574,7 @@ namespace winsw private int GetNextFileNumber(string ext, string baseDirectory, string baseFileName, DateTime now) { var nextFileNumber = 0; - var files = Directory.GetFiles(baseDirectory, string.Format("{0}.{1}.#*{2}", baseFileName, now.ToString(FilePattern), ext)); + var files = Directory.GetFiles(baseDirectory, string.Format("{0}.{1}.#*{2}", baseFileName, now.ToString(this.FilePattern), ext)); if (files.Length == 0) { nextFileNumber = 1; @@ -566,11 +588,12 @@ namespace winsw var filenameOnly = Path.GetFileNameWithoutExtension(f); var hashIndex = filenameOnly.IndexOf('#'); var lastNumberAsString = filenameOnly.Substring(hashIndex + 1, 4); - // var lastNumberAsString = filenameOnly.Substring(filenameOnly.Length - 4, 4); if (int.TryParse(lastNumberAsString, out int lastNumber)) { if (lastNumber > nextFileNumber) + { nextFileNumber = lastNumber; + } } else { @@ -584,7 +607,9 @@ namespace winsw } if (nextFileNumber == 0) + { throw new IOException("Cannot roll the file because matching pattern not found"); + } nextFileNumber++; } diff --git a/src/Core/WinSWCore/Logging/IServiceEventLogProvider.cs b/src/Core/WinSWCore/Logging/IServiceEventLogProvider.cs index f35d6e9..0c79fd0 100644 --- a/src/Core/WinSWCore/Logging/IServiceEventLogProvider.cs +++ b/src/Core/WinSWCore/Logging/IServiceEventLogProvider.cs @@ -1,6 +1,6 @@ using System.Diagnostics; -namespace winsw.Logging +namespace WinSW.Logging { /// /// Indicates that the class may reference the event log @@ -11,6 +11,6 @@ namespace winsw.Logging /// Locates Event Log for the service. /// /// Event Log or null if it is not avilable - EventLog? locate(); + EventLog? Locate(); } } diff --git a/src/Core/WinSWCore/Logging/ServiceEventLogAppender.cs b/src/Core/WinSWCore/Logging/ServiceEventLogAppender.cs index 0a62312..34b99ab 100644 --- a/src/Core/WinSWCore/Logging/ServiceEventLogAppender.cs +++ b/src/Core/WinSWCore/Logging/ServiceEventLogAppender.cs @@ -2,7 +2,7 @@ using log4net.Appender; using log4net.Core; -namespace winsw.Logging +namespace WinSW.Logging { /// /// Implementes service Event log appender for log4j. @@ -11,18 +11,18 @@ namespace winsw.Logging public class ServiceEventLogAppender : AppenderSkeleton { #pragma warning disable CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. - public IServiceEventLogProvider provider { get; set; } + public IServiceEventLogProvider Provider { get; set; } #pragma warning restore CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. - override protected void Append(LoggingEvent loggingEvent) + protected override void Append(LoggingEvent loggingEvent) { - EventLog? eventLog = provider.locate(); + EventLog? eventLog = this.Provider.Locate(); // We write the event iff the provider is ready - eventLog?.WriteEntry(loggingEvent.RenderedMessage, toEventLogEntryType(loggingEvent.Level)); + eventLog?.WriteEntry(loggingEvent.RenderedMessage, ToEventLogEntryType(loggingEvent.Level)); } - private static EventLogEntryType toEventLogEntryType(Level level) + private static EventLogEntryType ToEventLogEntryType(Level level) { if (level.Value >= Level.Error.Value) { diff --git a/src/Core/WinSWCore/Native/ConsoleApis.cs b/src/Core/WinSWCore/Native/ConsoleApis.cs index 9ad144a..0e0e8c5 100644 --- a/src/Core/WinSWCore/Native/ConsoleApis.cs +++ b/src/Core/WinSWCore/Native/ConsoleApis.cs @@ -1,6 +1,8 @@ -using System.Runtime.InteropServices; +#pragma warning disable SA1310 // Field names should not contain underscore -namespace winsw.Native +using System.Runtime.InteropServices; + +namespace WinSW.Native { internal static class ConsoleApis { diff --git a/src/Core/WinSWCore/Native/Errors.cs b/src/Core/WinSWCore/Native/Errors.cs index c52dbe9..490f289 100644 --- a/src/Core/WinSWCore/Native/Errors.cs +++ b/src/Core/WinSWCore/Native/Errors.cs @@ -1,4 +1,6 @@ -namespace winsw.Native +#pragma warning disable SA1310 // Field names should not contain underscore + +namespace WinSW.Native { internal static class Errors { diff --git a/src/Core/WinSWCore/Native/HandleApis.cs b/src/Core/WinSWCore/Native/HandleApis.cs index 126c81b..151fb71 100644 --- a/src/Core/WinSWCore/Native/HandleApis.cs +++ b/src/Core/WinSWCore/Native/HandleApis.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; -namespace winsw.Native +namespace WinSW.Native { internal static class HandleApis { diff --git a/src/Core/WinSWCore/Native/Kernel32.cs b/src/Core/WinSWCore/Native/Kernel32.cs index ba1afbb..4ce74ed 100755 --- a/src/Core/WinSWCore/Native/Kernel32.cs +++ b/src/Core/WinSWCore/Native/Kernel32.cs @@ -1,7 +1,7 @@ using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; -namespace winsw.Native +namespace WinSW.Native { internal static class Kernel32 { diff --git a/src/Core/WinSWCore/Native/Libraries.cs b/src/Core/WinSWCore/Native/Libraries.cs index 82d75f3..e2df5ab 100644 --- a/src/Core/WinSWCore/Native/Libraries.cs +++ b/src/Core/WinSWCore/Native/Libraries.cs @@ -1,4 +1,4 @@ -namespace winsw.Native +namespace WinSW.Native { internal static class Libraries { diff --git a/src/Core/WinSWCore/Native/ProcessApis.cs b/src/Core/WinSWCore/Native/ProcessApis.cs index 1c6292f..40ff013 100644 --- a/src/Core/WinSWCore/Native/ProcessApis.cs +++ b/src/Core/WinSWCore/Native/ProcessApis.cs @@ -1,8 +1,10 @@ -using System; +#pragma warning disable SA1310 // Field names should not contain underscore + +using System; using System.Runtime.InteropServices; using System.Security.Principal; -namespace winsw.Native +namespace WinSW.Native { internal static class ProcessApis { diff --git a/src/Core/WinSWCore/Native/Security.cs b/src/Core/WinSWCore/Native/Security.cs index a25006f..5f6f0c0 100644 --- a/src/Core/WinSWCore/Native/Security.cs +++ b/src/Core/WinSWCore/Native/Security.cs @@ -1,9 +1,9 @@ using System; using System.ComponentModel; using System.Runtime.InteropServices; -using static winsw.Native.SecurityApis; +using static WinSW.Native.SecurityApis; -namespace winsw.Native +namespace WinSW.Native { internal static class Security { diff --git a/src/Core/WinSWCore/Native/SecurityApis.cs b/src/Core/WinSWCore/Native/SecurityApis.cs index 4f28ffc..5b1c88b 100644 --- a/src/Core/WinSWCore/Native/SecurityApis.cs +++ b/src/Core/WinSWCore/Native/SecurityApis.cs @@ -1,7 +1,9 @@ -using System; +#pragma warning disable SA1310 // Field names should not contain underscore + +using System; using System.Runtime.InteropServices; -namespace winsw.Native +namespace WinSW.Native { internal static class SecurityApis { diff --git a/src/Core/WinSWCore/Native/Service.cs b/src/Core/WinSWCore/Native/Service.cs index bf2c4e2..d5e3f5e 100644 --- a/src/Core/WinSWCore/Native/Service.cs +++ b/src/Core/WinSWCore/Native/Service.cs @@ -1,8 +1,8 @@ using System; using System.Security.AccessControl; -using static winsw.Native.ServiceApis; +using static WinSW.Native.ServiceApis; -namespace winsw.Native +namespace WinSW.Native { public enum SC_ACTION_TYPE { @@ -106,7 +106,8 @@ namespace winsw.Native { fixed (SC_ACTION* actionsPtr = actions) { - if (!ChangeServiceConfig2(this.handle, + if (!ChangeServiceConfig2( + this.handle, ServiceConfigInfoLevels.FAILURE_ACTIONS, new SERVICE_FAILURE_ACTIONS { diff --git a/src/Core/WinSWCore/Native/ServiceApis.cs b/src/Core/WinSWCore/Native/ServiceApis.cs index 6d9785e..42d0e7b 100644 --- a/src/Core/WinSWCore/Native/ServiceApis.cs +++ b/src/Core/WinSWCore/Native/ServiceApis.cs @@ -2,7 +2,7 @@ using System.Runtime.InteropServices; using System.Security.AccessControl; -namespace winsw.Native +namespace WinSW.Native { internal static class ServiceApis { diff --git a/src/Core/WinSWCore/Native/Throw.cs b/src/Core/WinSWCore/Native/Throw.cs index a9aa795..b92689d 100644 --- a/src/Core/WinSWCore/Native/Throw.cs +++ b/src/Core/WinSWCore/Native/Throw.cs @@ -1,7 +1,7 @@ using System.ComponentModel; using System.Diagnostics; -namespace winsw.Native +namespace WinSW.Native { internal static class Throw { diff --git a/src/Core/WinSWCore/NullableAttributes.cs b/src/Core/WinSWCore/NullableAttributes.cs index 71aab86..a2a05fe 100644 --- a/src/Core/WinSWCore/NullableAttributes.cs +++ b/src/Core/WinSWCore/NullableAttributes.cs @@ -1,4 +1,5 @@ #if !NETCOREAPP +#pragma warning disable SA1502 // Element should not be on a single line namespace System.Diagnostics.CodeAnalysis { /// Specifies that null is allowed as an input even if the corresponding type disallows it. diff --git a/src/Core/WinSWCore/PeriodicRollingCalendar.cs b/src/Core/WinSWCore/PeriodicRollingCalendar.cs index 1725153..41b868c 100644 --- a/src/Core/WinSWCore/PeriodicRollingCalendar.cs +++ b/src/Core/WinSWCore/PeriodicRollingCalendar.cs @@ -1,33 +1,29 @@ using System; -// ReSharper disable InconsistentNaming - -namespace winsw +namespace WinSW { - /** - * This is largely borrowed from the logback Rolling Calendar. - **/ + // This is largely borrowed from the logback Rolling Calendar. public class PeriodicRollingCalendar { - private readonly string _format; - private readonly long _period; - private DateTime _currentRoll; - private DateTime _nextRoll; + private readonly string format; + private readonly long period; + private DateTime currentRoll; + private DateTime nextRoll; public PeriodicRollingCalendar(string format, long period) { - _format = format; - _period = period; - _currentRoll = DateTime.Now; + this.format = format; + this.period = period; + this.currentRoll = DateTime.Now; } - public void init() + public void Init() { - periodicityType = determinePeriodicityType(); - _nextRoll = nextTriggeringTime(_currentRoll, _period); + this.PeriodicityType = this.DeterminePeriodicityType(); + this.nextRoll = this.NextTriggeringTime(this.currentRoll, this.period); } - public enum PeriodicityType + public enum Periodicity { ERRONEOUS, TOP_OF_MILLISECOND, @@ -37,23 +33,23 @@ namespace winsw TOP_OF_DAY } - private static readonly PeriodicityType[] VALID_ORDERED_LIST = + private static readonly Periodicity[] ValidOrderedList = { - PeriodicityType.TOP_OF_MILLISECOND, PeriodicityType.TOP_OF_SECOND, PeriodicityType.TOP_OF_MINUTE, PeriodicityType.TOP_OF_HOUR, PeriodicityType.TOP_OF_DAY + Periodicity.TOP_OF_MILLISECOND, Periodicity.TOP_OF_SECOND, Periodicity.TOP_OF_MINUTE, Periodicity.TOP_OF_HOUR, Periodicity.TOP_OF_DAY }; - private PeriodicityType determinePeriodicityType() + private Periodicity DeterminePeriodicityType() { - PeriodicRollingCalendar periodicRollingCalendar = new PeriodicRollingCalendar(_format, _period); + PeriodicRollingCalendar periodicRollingCalendar = new PeriodicRollingCalendar(this.format, this.period); DateTime epoch = new DateTime(1970, 1, 1); - foreach (PeriodicityType i in VALID_ORDERED_LIST) + foreach (Periodicity i in ValidOrderedList) { - string r0 = epoch.ToString(_format); - periodicRollingCalendar.periodicityType = i; + string r0 = epoch.ToString(this.format); + periodicRollingCalendar.PeriodicityType = i; - DateTime next = periodicRollingCalendar.nextTriggeringTime(epoch, 1); - string r1 = next.ToString(_format); + DateTime next = periodicRollingCalendar.NextTriggeringTime(epoch, 1); + string r1 = next.ToString(this.format); if (r0 != r1) { @@ -61,45 +57,45 @@ namespace winsw } } - return PeriodicityType.ERRONEOUS; + return Periodicity.ERRONEOUS; } - private DateTime nextTriggeringTime(DateTime input, long increment) => periodicityType switch + private DateTime NextTriggeringTime(DateTime input, long increment) => this.PeriodicityType switch { - PeriodicityType.TOP_OF_MILLISECOND => + Periodicity.TOP_OF_MILLISECOND => new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, input.Second, input.Millisecond) .AddMilliseconds(increment), - PeriodicityType.TOP_OF_SECOND => + Periodicity.TOP_OF_SECOND => new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, input.Second) .AddSeconds(increment), - PeriodicityType.TOP_OF_MINUTE => + Periodicity.TOP_OF_MINUTE => new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, 0) .AddMinutes(increment), - PeriodicityType.TOP_OF_HOUR => + Periodicity.TOP_OF_HOUR => new DateTime(input.Year, input.Month, input.Day, input.Hour, 0, 0) .AddHours(increment), - PeriodicityType.TOP_OF_DAY => + Periodicity.TOP_OF_DAY => new DateTime(input.Year, input.Month, input.Day) .AddDays(increment), - _ => throw new Exception("invalid periodicity type: " + periodicityType), + _ => throw new Exception("invalid periodicity type: " + this.PeriodicityType), }; - public PeriodicityType periodicityType { get; set; } + public Periodicity PeriodicityType { get; set; } - public bool shouldRoll + public bool ShouldRoll { get { DateTime now = DateTime.Now; - if (now > _nextRoll) + if (now > this.nextRoll) { - _currentRoll = now; - _nextRoll = nextTriggeringTime(now, _period); + this.currentRoll = now; + this.nextRoll = this.NextTriggeringTime(now, this.period); return true; } @@ -107,6 +103,6 @@ namespace winsw } } - public string format => _currentRoll.ToString(_format); + public string Format => this.currentRoll.ToString(this.format); } } diff --git a/src/Core/WinSWCore/ServiceDescriptor.cs b/src/Core/WinSWCore/ServiceDescriptor.cs index 3e76cf5..e7a41bf 100755 --- a/src/Core/WinSWCore/ServiceDescriptor.cs +++ b/src/Core/WinSWCore/ServiceDescriptor.cs @@ -4,19 +4,18 @@ using System.Diagnostics; using System.IO; using System.Text; using System.Xml; -using winsw.Configuration; -using winsw.Native; -using winsw.Util; +using WinSW.Configuration; +using WinSW.Native; +using WinSW.Util; using WMI; -namespace winsw +namespace WinSW { /// /// In-memory representation of the configuration file. /// public class ServiceDescriptor : IWinSWConfiguration { - // ReSharper disable once InconsistentNaming protected readonly XmlDocument dom = new XmlDocument(); private readonly Dictionary environmentVariables; @@ -45,29 +44,35 @@ namespace winsw // find co-located configuration xml. We search up to the ancestor directories to simplify debugging, // as well as trimming off ".vshost" suffix (which is used during debugging) // Get the first parent to go into the recursive loop - string p = ExecutablePath; + string p = this.ExecutablePath; string baseName = Path.GetFileNameWithoutExtension(p); if (baseName.EndsWith(".vshost")) + { baseName = baseName.Substring(0, baseName.Length - 7); + } DirectoryInfo d = new DirectoryInfo(Path.GetDirectoryName(p)); while (true) { if (File.Exists(Path.Combine(d.FullName, baseName + ".xml"))) + { break; + } if (d.Parent is null) + { throw new FileNotFoundException("Unable to locate " + baseName + ".xml file within executable directory or any parents"); + } d = d.Parent; } - BaseName = baseName; - BasePath = Path.Combine(d.FullName, BaseName); + this.BaseName = baseName; + this.BasePath = Path.Combine(d.FullName, this.BaseName); try { - dom.Load(BasePath + ".xml"); + this.dom.Load(this.BasePath + ".xml"); } catch (XmlException e) { @@ -78,13 +83,13 @@ namespace winsw Environment.SetEnvironmentVariable("BASE", d.FullName); // ditto for ID - Environment.SetEnvironmentVariable("SERVICE_ID", Id); + Environment.SetEnvironmentVariable("SERVICE_ID", this.Id); // New name - Environment.SetEnvironmentVariable(WinSWSystem.ENVVAR_NAME_EXECUTABLE_PATH, ExecutablePath); + Environment.SetEnvironmentVariable(WinSWSystem.EnvVarNameExecutablePath, this.ExecutablePath); // Also inject system environment variables - Environment.SetEnvironmentVariable(WinSWSystem.ENVVAR_NAME_SERVICE_ID, Id); + Environment.SetEnvironmentVariable(WinSWSystem.EnvVarNameServiceId, this.Id); this.environmentVariables = this.LoadEnvironmentVariables(); } @@ -101,7 +106,6 @@ namespace winsw this.environmentVariables = this.LoadEnvironmentVariables(); } - // ReSharper disable once InconsistentNaming public static ServiceDescriptor FromXML(string xml) { var dom = new XmlDocument(); @@ -111,21 +115,23 @@ namespace winsw private string SingleElement(string tagName) { - return SingleElement(tagName, false)!; + return this.SingleElement(tagName, false)!; } private string? SingleElement(string tagName, bool optional) { - XmlNode? n = dom.SelectSingleNode("//" + tagName); + XmlNode? n = this.dom.SelectSingleNode("//" + tagName); if (n is null && !optional) + { throw new InvalidDataException("<" + tagName + "> is missing in configuration XML"); + } return n is null ? null : Environment.ExpandEnvironmentVariables(n.InnerText); } private bool SingleBoolElement(string tagName, bool defaultValue) { - XmlNode? e = dom.SelectSingleNode("//" + tagName); + XmlNode? e = this.dom.SelectSingleNode("//" + tagName); return e is null ? defaultValue : bool.Parse(e.InnerText); } @@ -139,8 +145,8 @@ namespace winsw private TimeSpan SingleTimeSpanElement(XmlNode parent, string tagName, TimeSpan defaultValue) { - string? value = SingleElement(tagName, true); - return value is null ? defaultValue : ParseTimeSpan(value); + string? value = this.SingleElement(tagName, true); + return value is null ? defaultValue : this.ParseTimeSpan(value); } private TimeSpan ParseTimeSpan(string v) @@ -175,14 +181,14 @@ namespace winsw /// /// Path to the executable. /// - public string Executable => SingleElement("executable"); + public string Executable => this.SingleElement("executable"); - public bool HideWindow => SingleBoolElement("hidewindow", Defaults.HideWindow); + public bool HideWindow => this.SingleBoolElement("hidewindow", Defaults.HideWindow); /// /// Optionally specify a different Path to an executable to shutdown the service. /// - public string? StopExecutable => SingleElement("stopexecutable", true); + public string? StopExecutable => this.SingleElement("stopexecutable", true); /// /// arguments or multiple optional argument elements which overrule the arguments element. @@ -191,14 +197,14 @@ namespace winsw { get { - string? arguments = AppendTags("argument", null); + string? arguments = this.AppendTags("argument", null); if (!(arguments is null)) { return arguments; } - XmlNode? argumentsNode = dom.SelectSingleNode("//arguments"); + XmlNode? argumentsNode = this.dom.SelectSingleNode("//arguments"); return argumentsNode is null ? Defaults.Arguments : Environment.ExpandEnvironmentVariables(argumentsNode.InnerText); } @@ -211,14 +217,14 @@ namespace winsw { get { - string? startArguments = AppendTags("startargument", null); + string? startArguments = this.AppendTags("startargument", null); if (!(startArguments is null)) { return startArguments; } - XmlNode? startArgumentsNode = dom.SelectSingleNode("//startarguments"); + XmlNode? startArgumentsNode = this.dom.SelectSingleNode("//startarguments"); return startArgumentsNode is null ? null : Environment.ExpandEnvironmentVariables(startArgumentsNode.InnerText); } @@ -231,14 +237,14 @@ namespace winsw { get { - string? stopArguments = AppendTags("stopargument", null); + string? stopArguments = this.AppendTags("stopargument", null); if (!(stopArguments is null)) { return stopArguments; } - XmlNode? stopArgumentsNode = dom.SelectSingleNode("//stoparguments"); + XmlNode? stopArgumentsNode = this.dom.SelectSingleNode("//stoparguments"); return stopArgumentsNode is null ? null : Environment.ExpandEnvironmentVariables(stopArgumentsNode.InnerText); } @@ -248,7 +254,7 @@ namespace winsw { get { - var wd = SingleElement("workingdirectory", true); + var wd = this.SingleElement("workingdirectory", true); return string.IsNullOrEmpty(wd) ? Defaults.WorkingDirectory : wd!; } } @@ -257,7 +263,7 @@ namespace winsw { get { - XmlNode? argumentNode = ExtensionsConfiguration; + XmlNode? argumentNode = this.ExtensionsConfiguration; XmlNodeList? extensions = argumentNode?.SelectNodes("extension"); if (extensions is null) { @@ -274,7 +280,7 @@ namespace winsw } } - public XmlNode? ExtensionsConfiguration => dom.SelectSingleNode("//extensions"); + public XmlNode? ExtensionsConfiguration => this.dom.SelectSingleNode("//extensions"); /// /// Combines the contents of all the elements of the given name, @@ -282,7 +288,7 @@ namespace winsw /// private string? AppendTags(string tagName, string? defaultValue = null) { - XmlNode? argumentNode = dom.SelectSingleNode("//" + tagName); + XmlNode? argumentNode = this.dom.SelectSingleNode("//" + tagName); if (argumentNode is null) { return defaultValue; @@ -290,7 +296,7 @@ namespace winsw StringBuilder arguments = new StringBuilder(); - XmlNodeList argumentNodeList = dom.SelectNodes("//" + tagName); + XmlNodeList argumentNodeList = this.dom.SelectNodes("//" + tagName); for (int i = 0; i < argumentNodeList.Count; i++) { arguments.Append(' '); @@ -325,7 +331,7 @@ namespace winsw { get { - XmlNode? loggingNode = dom.SelectSingleNode("//logpath"); + XmlNode? loggingNode = this.dom.SelectSingleNode("//logpath"); return loggingNode is null ? Defaults.LogDirectory @@ -340,7 +346,7 @@ namespace winsw string? mode = null; // first, backward compatibility with older configuration - XmlElement? e = (XmlElement?)dom.SelectSingleNode("//logmode"); + XmlElement? e = (XmlElement?)this.dom.SelectSingleNode("//logmode"); if (e != null) { mode = e.InnerText; @@ -348,9 +354,11 @@ namespace winsw else { // this is more modern way, to support nested elements as configuration - e = (XmlElement?)dom.SelectSingleNode("//log"); + e = (XmlElement?)this.dom.SelectSingleNode("//log"); if (e != null) + { mode = e.GetAttribute("mode"); + } } return mode ?? Defaults.LogMode; @@ -361,21 +369,21 @@ namespace winsw { get { - XmlNode? loggingName = dom.SelectSingleNode("//logname"); + XmlNode? loggingName = this.dom.SelectSingleNode("//logname"); - return loggingName is null ? BaseName : Environment.ExpandEnvironmentVariables(loggingName.InnerText); + return loggingName is null ? this.BaseName : Environment.ExpandEnvironmentVariables(loggingName.InnerText); } } - public bool OutFileDisabled => SingleBoolElement("outfiledisabled", Defaults.OutFileDisabled); + public bool OutFileDisabled => this.SingleBoolElement("outfiledisabled", Defaults.OutFileDisabled); - public bool ErrFileDisabled => SingleBoolElement("errfiledisabled", Defaults.ErrFileDisabled); + public bool ErrFileDisabled => this.SingleBoolElement("errfiledisabled", Defaults.ErrFileDisabled); public string OutFilePattern { get { - XmlNode? loggingName = dom.SelectSingleNode("//outfilepattern"); + XmlNode? loggingName = this.dom.SelectSingleNode("//outfilepattern"); return loggingName is null ? Defaults.OutFilePattern : Environment.ExpandEnvironmentVariables(loggingName.InnerText); } @@ -385,7 +393,7 @@ namespace winsw { get { - XmlNode? loggingName = dom.SelectSingleNode("//errfilepattern"); + XmlNode? loggingName = this.dom.SelectSingleNode("//errfilepattern"); return loggingName is null ? Defaults.ErrFilePattern : Environment.ExpandEnvironmentVariables(loggingName.InnerText); } @@ -395,25 +403,25 @@ namespace winsw { get { - XmlElement? e = (XmlElement?)dom.SelectSingleNode("//logmode"); + XmlElement? e = (XmlElement?)this.dom.SelectSingleNode("//logmode"); // this is more modern way, to support nested elements as configuration - e ??= (XmlElement?)dom.SelectSingleNode("//log")!; // WARNING: NRE + e ??= (XmlElement?)this.dom.SelectSingleNode("//log")!; // WARNING: NRE int sizeThreshold; - switch (LogMode) + switch (this.LogMode) { case "rotate": - return new SizeBasedRollingLogAppender(LogDirectory, LogName, OutFileDisabled, ErrFileDisabled, OutFilePattern, ErrFilePattern); + return new SizeBasedRollingLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern); case "none": return new IgnoreLogAppender(); case "reset": - return new ResetLogAppender(LogDirectory, LogName, OutFileDisabled, ErrFileDisabled, OutFilePattern, ErrFilePattern); + return new ResetLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern); case "roll": - return new RollingLogAppender(LogDirectory, LogName, OutFileDisabled, ErrFileDisabled, OutFilePattern, ErrFilePattern); + return new RollingLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern); case "roll-by-time": XmlNode? patternNode = e.SelectSingleNode("pattern"); @@ -423,19 +431,19 @@ namespace winsw } var pattern = patternNode.InnerText; - int period = SingleIntElement(e, "period", 1); - return new TimeBasedRollingLogAppender(LogDirectory, LogName, OutFileDisabled, ErrFileDisabled, OutFilePattern, ErrFilePattern, pattern, period); + int period = this.SingleIntElement(e, "period", 1); + return new TimeBasedRollingLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern, pattern, period); case "roll-by-size": - sizeThreshold = SingleIntElement(e, "sizeThreshold", 10 * 1024) * SizeBasedRollingLogAppender.BYTES_PER_KB; - int keepFiles = SingleIntElement(e, "keepFiles", SizeBasedRollingLogAppender.DEFAULT_FILES_TO_KEEP); - return new SizeBasedRollingLogAppender(LogDirectory, LogName, OutFileDisabled, ErrFileDisabled, OutFilePattern, ErrFilePattern, sizeThreshold, keepFiles); + sizeThreshold = this.SingleIntElement(e, "sizeThreshold", 10 * 1024) * SizeBasedRollingLogAppender.BytesPerKB; + int keepFiles = this.SingleIntElement(e, "keepFiles", SizeBasedRollingLogAppender.DefaultFilesToKeep); + return new SizeBasedRollingLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern, sizeThreshold, keepFiles); case "append": - return new DefaultLogAppender(LogDirectory, LogName, OutFileDisabled, ErrFileDisabled, OutFilePattern, ErrFilePattern); + return new DefaultLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern); case "roll-by-size-time": - sizeThreshold = SingleIntElement(e, "sizeThreshold", 10 * 1024) * RollingSizeTimeLogAppender.BYTES_PER_KB; + sizeThreshold = this.SingleIntElement(e, "sizeThreshold", 10 * 1024) * RollingSizeTimeLogAppender.BytesPerKB; XmlNode? filePatternNode = e.SelectSingleNode("pattern"); if (filePatternNode is null) { @@ -448,7 +456,9 @@ namespace winsw { // validate it if (!TimeSpan.TryParse(autoRollAtTimeNode.InnerText, out TimeSpan autoRollAtTimeValue)) + { throw new InvalidDataException("Roll-Size-Time Based rolling policy is specified but autoRollAtTime does not match the TimeSpan format HH:mm:ss found in configuration XML."); + } autoRollAtTime = autoRollAtTimeValue; } @@ -459,7 +469,9 @@ namespace winsw { // validate it if (!int.TryParse(zipolderthannumdaysNode.InnerText, out int zipolderthannumdaysValue)) + { throw new InvalidDataException("Roll-Size-Time Based rolling policy is specified but zipOlderThanNumDays does not match the int format found in configuration XML."); + } zipolderthannumdays = zipolderthannumdaysValue; } @@ -467,10 +479,10 @@ namespace winsw XmlNode? zipdateformatNode = e.SelectSingleNode("zipDateFormat"); string zipdateformat = zipdateformatNode is null ? "yyyyMM" : zipdateformatNode.InnerText; - return new RollingSizeTimeLogAppender(LogDirectory, LogName, OutFileDisabled, ErrFileDisabled, OutFilePattern, ErrFilePattern, sizeThreshold, filePatternNode.InnerText, autoRollAtTime, zipolderthannumdays, zipdateformat); + return new RollingSizeTimeLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern, sizeThreshold, filePatternNode.InnerText, autoRollAtTime, zipolderthannumdays, zipdateformat); default: - throw new InvalidDataException("Undefined logging mode: " + LogMode); + throw new InvalidDataException("Undefined logging mode: " + this.LogMode); } } } @@ -482,7 +494,7 @@ namespace winsw { get { - XmlNodeList? nodeList = dom.SelectNodes("//depend"); + XmlNodeList? nodeList = this.dom.SelectNodes("//depend"); if (nodeList is null) { return Defaults.ServiceDependencies; @@ -498,11 +510,11 @@ namespace winsw } } - public string Id => SingleElement("id"); + public string Id => this.SingleElement("id"); - public string Caption => SingleElement("name"); + public string Caption => this.SingleElement("name"); - public string Description => SingleElement("description"); + public string Description => this.SingleElement("description"); /// /// Start mode of the Service @@ -511,9 +523,11 @@ namespace winsw { get { - string? p = SingleElement("startmode", true); + string? p = this.SingleElement("startmode", true); if (p is null) + { return Defaults.StartMode; + } try { @@ -536,32 +550,32 @@ 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 => dom.SelectSingleNode("//delayedAutoStart") != null; + public bool DelayedAutoStart => this.dom.SelectSingleNode("//delayedAutoStart") != null; /// /// 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 => dom.SelectSingleNode("//beeponshutdown") != null; + public bool BeepOnShutdown => this.dom.SelectSingleNode("//beeponshutdown") != null; /// /// The estimated time required for a pending stop operation (default 15 secs). /// Before the specified amount of time has elapsed, the service should make its next call to the SetServiceStatus function /// with either an incremented checkPoint value or a change in currentState. (see http://msdn.microsoft.com/en-us/library/ms685996.aspx) /// - public TimeSpan WaitHint => SingleTimeSpanElement(dom, "waithint", Defaults.WaitHint); + public TimeSpan WaitHint => this.SingleTimeSpanElement(this.dom, "waithint", Defaults.WaitHint); /// /// The time before the service should make its next call to the SetServiceStatus function /// with an incremented checkPoint value (default 1 sec). /// Do not wait longer than the wait hint. A good interval is one-tenth of the wait hint but not less than 1 second and not more than 10 seconds. /// - public TimeSpan SleepTime => SingleTimeSpanElement(dom, "sleeptime", Defaults.SleepTime); + public TimeSpan SleepTime => this.SingleTimeSpanElement(this.dom, "sleeptime", Defaults.SleepTime); /// /// True if the service can interact with the desktop. /// - public bool Interactive => dom.SelectSingleNode("//interactive") != null; + public bool Interactive => this.dom.SelectSingleNode("//interactive") != null; /// /// Environment variable overrides @@ -576,7 +590,7 @@ namespace winsw { get { - XmlNodeList? nodeList = dom.SelectNodes("//download"); + XmlNodeList? nodeList = this.dom.SelectNodes("//download"); if (nodeList is null) { return Defaults.Downloads; @@ -599,7 +613,7 @@ namespace winsw { get { - XmlNodeList? childNodes = dom.SelectNodes("//onfailure"); + XmlNodeList? childNodes = this.dom.SelectNodes("//onfailure"); if (childNodes is null) { return new SC_ACTION[0]; @@ -618,18 +632,18 @@ namespace winsw _ => throw new Exception("Invalid failure action: " + action) }; XmlAttribute? delay = node.Attributes["delay"]; - result[i] = new SC_ACTION(type, delay != null ? ParseTimeSpan(delay.Value) : TimeSpan.Zero); + result[i] = new SC_ACTION(type, delay != null ? this.ParseTimeSpan(delay.Value) : TimeSpan.Zero); } return result; } } - public TimeSpan ResetFailureAfter => SingleTimeSpanElement(dom, "resetfailure", Defaults.ResetFailureAfter); + public TimeSpan ResetFailureAfter => this.SingleTimeSpanElement(this.dom, "resetfailure", Defaults.ResetFailureAfter); protected string? GetServiceAccountPart(string subNodeName) { - XmlNode? node = dom.SelectSingleNode("//serviceaccount"); + XmlNode? node = this.dom.SelectSingleNode("//serviceaccount"); if (node != null) { @@ -643,28 +657,28 @@ namespace winsw return null; } - protected string? AllowServiceLogon => GetServiceAccountPart("allowservicelogon"); + protected string? AllowServiceLogon => this.GetServiceAccountPart("allowservicelogon"); - protected internal string? ServiceAccountDomain => GetServiceAccountPart("domain"); + protected internal string? ServiceAccountDomain => this.GetServiceAccountPart("domain"); - protected internal string? ServiceAccountName => GetServiceAccountPart("user"); + protected internal string? ServiceAccountName => this.GetServiceAccountPart("user"); - public string? ServiceAccountPassword => GetServiceAccountPart("password"); + public string? ServiceAccountPassword => this.GetServiceAccountPart("password"); - public string? ServiceAccountUser => ServiceAccountName is null ? null : (ServiceAccountDomain ?? ".") + "\\" + ServiceAccountName; + public string? ServiceAccountUser => this.ServiceAccountName is null ? null : (this.ServiceAccountDomain ?? ".") + "\\" + this.ServiceAccountName; public bool HasServiceAccount() { - return !string.IsNullOrEmpty(ServiceAccountName); + return !string.IsNullOrEmpty(this.ServiceAccountName); } public bool AllowServiceAcountLogonRight { get { - if (AllowServiceLogon != null) + if (this.AllowServiceLogon != null) { - if (bool.TryParse(AllowServiceLogon, out bool parsedvalue)) + if (bool.TryParse(this.AllowServiceLogon, out bool parsedvalue)) { return parsedvalue; } @@ -677,13 +691,13 @@ namespace winsw /// /// Time to wait for the service to gracefully shutdown the executable before we forcibly kill it /// - public TimeSpan StopTimeout => SingleTimeSpanElement(dom, "stoptimeout", Defaults.StopTimeout); + public TimeSpan StopTimeout => this.SingleTimeSpanElement(this.dom, "stoptimeout", Defaults.StopTimeout); public bool StopParentProcessFirst { get { - var value = SingleElement("stopparentprocessfirst", true); + var value = this.SingleElement("stopparentprocessfirst", true); if (bool.TryParse(value, out bool result)) { return result; @@ -700,19 +714,21 @@ namespace winsw { get { - string? p = SingleElement("priority", true); + string? p = this.SingleElement("priority", true); if (p is null) + { return Defaults.Priority; + } return (ProcessPriorityClass)Enum.Parse(typeof(ProcessPriorityClass), p, true); } } - public string? SecurityDescriptor => SingleElement("securityDescriptor", true); + public string? SecurityDescriptor => this.SingleElement("securityDescriptor", true); private Dictionary LoadEnvironmentVariables() { - XmlNodeList nodeList = dom.SelectNodes("//env"); + XmlNodeList nodeList = this.dom.SelectNodes("//env"); Dictionary environment = new Dictionary(nodeList.Count); for (int i = 0; i < nodeList.Count; i++) { diff --git a/src/Core/WinSWCore/Util/FileHelper.cs b/src/Core/WinSWCore/Util/FileHelper.cs index 23efdec..ecc4f3c 100644 --- a/src/Core/WinSWCore/Util/FileHelper.cs +++ b/src/Core/WinSWCore/Util/FileHelper.cs @@ -6,7 +6,7 @@ using System.IO; using System.Runtime.InteropServices; #endif -namespace winsw.Util +namespace WinSW.Util { public static class FileHelper { diff --git a/src/Core/WinSWCore/Util/ProcessHelper.cs b/src/Core/WinSWCore/Util/ProcessHelper.cs index 0c22adf..28fbb37 100644 --- a/src/Core/WinSWCore/Util/ProcessHelper.cs +++ b/src/Core/WinSWCore/Util/ProcessHelper.cs @@ -5,7 +5,7 @@ using System.Management; using System.Threading; using log4net; -namespace winsw.Util +namespace WinSW.Util { /// /// Provides helper classes for Process Management @@ -76,6 +76,7 @@ namespace winsw.Util { Logger.Warn("Process " + pid + " did not respond to Ctrl+C signal - Killing as fallback"); } + proc.Kill(); } catch (Exception ex) @@ -126,14 +127,14 @@ namespace winsw.Util /// Once the process exits, the callback will be invoked. /// /// Process object to be used - /// Arguments to be passed /// Executable, which should be invoked + /// Arguments to be passed /// Additional environment variables /// Working directory /// Priority /// Completion callback. If null, the completion won't be monitored - /// Log handler. If enabled, logs will be redirected to the process and then reported /// Redirect standard input + /// Log handler. If enabled, logs will be redirected to the process and then reported public static void StartProcessAndCallbackForExit( Process processToStart, string? executable = null, @@ -161,6 +162,7 @@ namespace winsw.Util foreach (string key in envVars.Keys) { Environment.SetEnvironmentVariable(key, envVars[key]); + // DONTDO: ps.EnvironmentVariables[key] = envs[key]; // bugged (lower cases all variable names due to StringDictionary being used, see http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=326163) } @@ -178,7 +180,7 @@ namespace winsw.Util if (logHandler != null) { Logger.Debug("Forwarding logs of the process " + processToStart + " to " + logHandler); - logHandler.log(processToStart.StandardOutput, processToStart.StandardError); + logHandler.Log(processToStart.StandardOutput, processToStart.StandardError); } // monitor the completion of the process diff --git a/src/Core/WinSWCore/Util/SignalHelper.cs b/src/Core/WinSWCore/Util/SignalHelper.cs index cffc249..7be1bfb 100644 --- a/src/Core/WinSWCore/Util/SignalHelper.cs +++ b/src/Core/WinSWCore/Util/SignalHelper.cs @@ -4,9 +4,9 @@ using System.ComponentModel; using System.Diagnostics; using System.Runtime.InteropServices; using log4net; -using winsw.Native; +using WinSW.Native; -namespace winsw.Util +namespace WinSW.Util { internal static class SignalHelper { diff --git a/src/Core/WinSWCore/Util/XmlHelper.cs b/src/Core/WinSWCore/Util/XmlHelper.cs index f28a2f0..23d0ccd 100644 --- a/src/Core/WinSWCore/Util/XmlHelper.cs +++ b/src/Core/WinSWCore/Util/XmlHelper.cs @@ -3,7 +3,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Xml; -namespace winsw.Util +namespace WinSW.Util { public class XmlHelper { @@ -19,7 +19,9 @@ namespace winsw.Util { XmlNode? n = node.SelectSingleNode(tagName); if (n is null && !optional) + { throw new InvalidDataException("<" + tagName + "> is missing in configuration XML"); + } return n is null ? null : Environment.ExpandEnvironmentVariables(n.InnerText); } @@ -36,7 +38,9 @@ namespace winsw.Util { XmlNode? n = node.SelectSingleNode(tagName); if (n is null && !optional) + { throw new InvalidDataException("<" + tagName + "> is missing in configuration XML"); + } return n; } @@ -69,7 +73,9 @@ namespace winsw.Util public static TAttributeType SingleAttribute(XmlElement node, string attributeName, [AllowNull] TAttributeType defaultValue) { if (!node.HasAttribute(attributeName)) + { return defaultValue; + } string rawValue = node.GetAttribute(attributeName); string substitutedValue = Environment.ExpandEnvironmentVariables(rawValue); @@ -90,7 +96,9 @@ namespace winsw.Util where TAttributeType : struct { if (!node.HasAttribute(attributeName)) + { return defaultValue; + } string rawValue = node.GetAttribute(attributeName); string substitutedValue = Environment.ExpandEnvironmentVariables(rawValue); @@ -102,7 +110,8 @@ namespace winsw.Util } catch (ArgumentException ex) { - throw new InvalidDataException("Cannot parse <" + attributeName + "> Enum value from string '" + substitutedValue + + throw new InvalidDataException( + "Cannot parse <" + attributeName + "> Enum value from string '" + substitutedValue + "'. Enum type: " + typeof(TAttributeType), ex); } #else diff --git a/src/Core/WinSWCore/WinSWCore.csproj b/src/Core/WinSWCore/WinSWCore.csproj index 7162559..4ace542 100644 --- a/src/Core/WinSWCore/WinSWCore.csproj +++ b/src/Core/WinSWCore/WinSWCore.csproj @@ -11,6 +11,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/src/Core/WinSWCore/WinSWException.cs b/src/Core/WinSWCore/WinSWException.cs index 6fed7b7..86bf04b 100644 --- a/src/Core/WinSWCore/WinSWException.cs +++ b/src/Core/WinSWCore/WinSWException.cs @@ -1,15 +1,17 @@ using System; -namespace winsw +namespace WinSW { public class WinSWException : Exception { public WinSWException(string message) : base(message) - { } + { + } public WinSWException(string message, Exception innerException) : base(message, innerException) - { } + { + } } } diff --git a/src/Core/WinSWCore/WinSWSystem.cs b/src/Core/WinSWCore/WinSWSystem.cs index b1739db..bc3190f 100644 --- a/src/Core/WinSWCore/WinSWSystem.cs +++ b/src/Core/WinSWCore/WinSWSystem.cs @@ -1,4 +1,4 @@ -namespace winsw +namespace WinSW { /// /// Class, which contains generic information about WinSW runtime. @@ -9,17 +9,17 @@ /// /// Prefix for all environment variables being injected for WinSW /// - public static readonly string SYSTEM_EVNVVAR_PREFIX = "WINSW_"; + public static readonly string SystemEnvVarPrefix = "WINSW_"; /// /// Variable, which points to the service ID. /// It may be used to determine runaway processes. /// - public static string ENVVAR_NAME_SERVICE_ID => SYSTEM_EVNVVAR_PREFIX + "SERVICE_ID"; + public static string EnvVarNameServiceId => SystemEnvVarPrefix + "SERVICE_ID"; /// /// Variable, which specifies path to the executable being launched by WinSW. /// - public static string ENVVAR_NAME_EXECUTABLE_PATH => SYSTEM_EVNVVAR_PREFIX + "EXECUTABLE"; + public static string EnvVarNameExecutablePath => SystemEnvVarPrefix + "EXECUTABLE"; } } diff --git a/src/Core/WinSWCore/Wmi.cs b/src/Core/WinSWCore/Wmi.cs index 045f30d..5259a19 100755 --- a/src/Core/WinSWCore/Wmi.cs +++ b/src/Core/WinSWCore/Wmi.cs @@ -48,7 +48,7 @@ namespace WMI public WmiException(string message, ReturnValue code) : base(message) { - ErrorCode = code; + this.ErrorCode = code; } public WmiException(ReturnValue code) @@ -64,13 +64,15 @@ namespace WMI { public readonly string Name; - public WmiClassName(string name) => Name = name; + public WmiClassName(string name) => this.Name = name; } /// /// Marker interface to denote a collection in WMI. /// - public interface IWmiCollection { } + public interface IWmiCollection + { + } /// /// Marker interface to denote an individual managed object @@ -109,7 +111,9 @@ namespace WMI { uint code = (uint)result["returnValue"]; if (code != 0) + { throw new WmiException((ReturnValue)code); + } } protected ManagementBaseObject GetMethodParameters(ManagementObject wmiObject, string methodName, ParameterInfo[] methodParameters, object[] arguments) @@ -174,20 +178,23 @@ namespace WMI { ParameterInfo[] methodParameters = method.GetParameters(); - if (method.Name == nameof(Win32Services.Select)) + if (method.Name == nameof(IWin32Services.Select)) { // select method to find instances StringBuilder query = new StringBuilder("SELECT * FROM ").Append(this.className).Append(" WHERE "); for (int i = 0; i < arguments.Length; i++) { if (i != 0) + { query.Append(" AND "); + } query.Append(' ').Append(Capitalize(methodParameters[i].Name!)).Append(" = '").Append(arguments[i]).Append('\''); } using ManagementObjectSearcher searcher = new ManagementObjectSearcher(this.wmiClass.Scope, new ObjectQuery(query.ToString())); using ManagementObjectCollection results = searcher.Get(); + // TODO: support collections foreach (ManagementObject wmiObject in results) { @@ -209,7 +216,8 @@ namespace WMI /// /// Obtains an object that corresponds to a table in WMI, which is a collection of a managed object. /// - public T GetCollection() where T : IWmiCollection + public T GetCollection() + where T : IWmiCollection { WmiClassName className = (WmiClassName)typeof(T).GetCustomAttributes(typeof(WmiClassName), false)[0]; diff --git a/src/Core/WinSWCore/WmiSchema.cs b/src/Core/WinSWCore/WmiSchema.cs index 959469b..2686204 100755 --- a/src/Core/WinSWCore/WmiSchema.cs +++ b/src/Core/WinSWCore/WmiSchema.cs @@ -1,5 +1,4 @@ - -namespace WMI +namespace WMI { public enum ServiceType { @@ -26,18 +25,22 @@ namespace WMI /// Device driver started by the operating system loader. This value is valid only for driver services. /// Boot, + /// /// Device driver started by the operating system initialization process. This value is valid only for driver services. /// System, + /// /// Service to be started automatically by the Service Control Manager during system startup. /// Automatic, + /// /// Service to be started by the Service Control Manager when a process calls the StartService method. /// Manual, + /// /// Service that can no longer be started. /// @@ -45,22 +48,25 @@ namespace WMI } [WmiClassName("Win32_Service")] - public interface Win32Services : IWmiCollection + public interface IWin32Services : IWmiCollection { // ReturnValue Create(bool desktopInteract, string displayName, int errorControl, string loadOrderGroup, string loadOrderGroupDependencies, string name, string pathName, string serviceDependencies, string serviceType, string startMode, string startName, string startPassword); void Create(string name, string displayName, string pathName, ServiceType serviceType, ErrorControl errorControl, string startMode, bool desktopInteract, string? startName, string? startPassword, string[] serviceDependencies); void Create(string name, string displayName, string pathName, ServiceType serviceType, ErrorControl errorControl, string startMode, bool desktopInteract, string[] serviceDependencies); - Win32Service? Select(string name); + IWin32Service? Select(string name); } // https://docs.microsoft.com/windows/win32/cimwin32prov/win32-service - public interface Win32Service : IWmiObject + public interface IWin32Service : IWmiObject { bool Started { get; } + void Delete(); + void StartService(); + void StopService(); } } diff --git a/src/Plugins/RunawayProcessKiller/NativeMethods.cs b/src/Plugins/RunawayProcessKiller/NativeMethods.cs index 3b92382..60c5db2 100644 --- a/src/Plugins/RunawayProcessKiller/NativeMethods.cs +++ b/src/Plugins/RunawayProcessKiller/NativeMethods.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; -namespace winsw.Plugins.RunawayProcessKiller +namespace WinSW.Plugins.RunawayProcessKiller { public partial class RunawayProcessKillerExtension { diff --git a/src/Plugins/RunawayProcessKiller/RunawayProcessKillerExtension.cs b/src/Plugins/RunawayProcessKiller/RunawayProcessKillerExtension.cs index 1623004..d3196e4 100644 --- a/src/Plugins/RunawayProcessKiller/RunawayProcessKillerExtension.cs +++ b/src/Plugins/RunawayProcessKiller/RunawayProcessKillerExtension.cs @@ -5,11 +5,11 @@ using System.IO; using System.Text; using System.Xml; using log4net; -using winsw.Extensions; -using winsw.Util; -using static winsw.Plugins.RunawayProcessKiller.RunawayProcessKillerExtension.NativeMethods; +using WinSW.Extensions; +using WinSW.Util; +using static WinSW.Plugins.RunawayProcessKiller.RunawayProcessKillerExtension.NativeMethods; -namespace winsw.Plugins.RunawayProcessKiller +namespace WinSW.Plugins.RunawayProcessKiller { public partial class RunawayProcessKillerExtension : AbstractWinSWExtension { @@ -183,13 +183,13 @@ namespace winsw.Plugins.RunawayProcessKiller { // We expect the upper logic to process any errors // TODO: a better parser API for types would be useful - Pidfile = XmlHelper.SingleElement(node, "pidfile", false)!; - StopTimeout = TimeSpan.FromMilliseconds(int.Parse(XmlHelper.SingleElement(node, "stopTimeout", false)!)); - StopParentProcessFirst = bool.Parse(XmlHelper.SingleElement(node, "stopParentFirst", false)!); - ServiceId = descriptor.Id; + this.Pidfile = XmlHelper.SingleElement(node, "pidfile", false)!; + this.StopTimeout = TimeSpan.FromMilliseconds(int.Parse(XmlHelper.SingleElement(node, "stopTimeout", false)!)); + this.StopParentProcessFirst = bool.Parse(XmlHelper.SingleElement(node, "stopParentFirst", false)!); + this.ServiceId = descriptor.Id; // TODO: Consider making it documented var checkWinSWEnvironmentVariable = XmlHelper.SingleElement(node, "checkWinSWEnvironmentVariable", true); - CheckWinSWEnvironmentVariable = checkWinSWEnvironmentVariable is null ? true : bool.Parse(checkWinSWEnvironmentVariable); + this.CheckWinSWEnvironmentVariable = checkWinSWEnvironmentVariable is null ? true : bool.Parse(checkWinSWEnvironmentVariable); } /// @@ -200,16 +200,16 @@ namespace winsw.Plugins.RunawayProcessKiller { // Read PID file from the disk int pid; - if (File.Exists(Pidfile)) + if (File.Exists(this.Pidfile)) { string pidstring; try { - pidstring = File.ReadAllText(Pidfile); + pidstring = File.ReadAllText(this.Pidfile); } catch (Exception ex) { - Logger.Error("Cannot read PID file from " + Pidfile, ex); + Logger.Error("Cannot read PID file from " + this.Pidfile, ex); return; } @@ -219,13 +219,13 @@ namespace winsw.Plugins.RunawayProcessKiller } catch (FormatException e) { - Logger.Error("Invalid PID file number in '" + Pidfile + "'. The runaway process won't be checked", e); + Logger.Error("Invalid PID file number in '" + this.Pidfile + "'. The runaway process won't be checked", e); return; } } else { - Logger.Warn("The requested PID file '" + Pidfile + "' does not exist. The runaway process won't be checked"); + Logger.Warn("The requested PID file '" + this.Pidfile + "' does not exist. The runaway process won't be checked"); return; } @@ -243,9 +243,9 @@ namespace winsw.Plugins.RunawayProcessKiller } // Ensure the process references the service - string expectedEnvVarName = WinSWSystem.ENVVAR_NAME_SERVICE_ID; + string expectedEnvVarName = WinSWSystem.EnvVarNameServiceId; string? affiliatedServiceId = ReadEnvironmentVariable(proc.Handle, expectedEnvVarName); - if (affiliatedServiceId is null && CheckWinSWEnvironmentVariable) + if (affiliatedServiceId is null && this.CheckWinSWEnvironmentVariable) { Logger.Warn("The process " + pid + " has no " + expectedEnvVarName + " environment variable defined. " + "The process has not been started by WinSW, hence it won't be terminated."); @@ -254,10 +254,10 @@ namespace winsw.Plugins.RunawayProcessKiller } // Check the service ID value - if (CheckWinSWEnvironmentVariable && !ServiceId.Equals(affiliatedServiceId)) + if (this.CheckWinSWEnvironmentVariable && !this.ServiceId.Equals(affiliatedServiceId)) { Logger.Warn("The process " + pid + " has been started by Windows service with ID='" + affiliatedServiceId + "'. " - + "It is another service (current service id is '" + ServiceId + "'), hence the process won't be terminated."); + + "It is another service (current service id is '" + this.ServiceId + "'), hence the process won't be terminated."); return; } @@ -265,7 +265,7 @@ namespace winsw.Plugins.RunawayProcessKiller StringBuilder bldr = new StringBuilder("Stopping the runaway process (pid="); bldr.Append(pid); bldr.Append(") and its children. Environment was "); - if (!CheckWinSWEnvironmentVariable) + if (!this.CheckWinSWEnvironmentVariable) { bldr.Append("not "); } @@ -285,14 +285,14 @@ namespace winsw.Plugins.RunawayProcessKiller /// public override void OnProcessStarted(Process process) { - Logger.Info("Recording PID of the started process:" + process.Id + ". PID file destination is " + Pidfile); + Logger.Info("Recording PID of the started process:" + process.Id + ". PID file destination is " + this.Pidfile); try { - File.WriteAllText(Pidfile, process.Id.ToString()); + File.WriteAllText(this.Pidfile, process.Id.ToString()); } catch (Exception ex) { - Logger.Error("Cannot update the PID file " + Pidfile, ex); + Logger.Error("Cannot update the PID file " + this.Pidfile, ex); } } } diff --git a/src/Plugins/SharedDirectoryMapper/SharedDirectoryMapper.cs b/src/Plugins/SharedDirectoryMapper/SharedDirectoryMapper.cs index 17b486b..4fb45f3 100644 --- a/src/Plugins/SharedDirectoryMapper/SharedDirectoryMapper.cs +++ b/src/Plugins/SharedDirectoryMapper/SharedDirectoryMapper.cs @@ -1,10 +1,10 @@ using System.Collections.Generic; using System.Xml; using log4net; -using winsw.Extensions; -using winsw.Util; +using WinSW.Extensions; +using WinSW.Util; -namespace winsw.Plugins.SharedDirectoryMapper +namespace WinSW.Plugins.SharedDirectoryMapper { public class SharedDirectoryMapper : AbstractWinSWExtension { @@ -22,7 +22,7 @@ namespace winsw.Plugins.SharedDirectoryMapper public SharedDirectoryMapper(bool enableMapping, string directoryUNC, string driveLabel) { SharedDirectoryMapperConfig config = new SharedDirectoryMapperConfig(enableMapping, driveLabel, directoryUNC); - _entries.Add(config); + this._entries.Add(config); } public override void Configure(ServiceDescriptor descriptor, XmlNode node) @@ -35,7 +35,7 @@ namespace winsw.Plugins.SharedDirectoryMapper if (mapNodes[i] is XmlElement mapElement) { var config = SharedDirectoryMapperConfig.FromXml(mapElement); - _entries.Add(config); + this._entries.Add(config); } } } @@ -43,40 +43,40 @@ namespace winsw.Plugins.SharedDirectoryMapper public override void OnWrapperStarted() { - foreach (SharedDirectoryMapperConfig config in _entries) + foreach (SharedDirectoryMapperConfig config in this._entries) { if (config.EnableMapping) { - Logger.Info(DisplayName + ": Mapping shared directory " + config.UNCPath + " to " + config.Label); + Logger.Info(this.DisplayName + ": Mapping shared directory " + config.UNCPath + " to " + config.Label); try { - _mapper.MapDirectory(config.Label, config.UNCPath); + this._mapper.MapDirectory(config.Label, config.UNCPath); } catch (MapperException ex) { - HandleMappingError(config, ex); + this.HandleMappingError(config, ex); } } else { - Logger.Warn(DisplayName + ": Mapping of " + config.Label + " is disabled"); + Logger.Warn(this.DisplayName + ": Mapping of " + config.Label + " is disabled"); } } } public override void BeforeWrapperStopped() { - foreach (SharedDirectoryMapperConfig config in _entries) + foreach (SharedDirectoryMapperConfig config in this._entries) { if (config.EnableMapping) { try { - _mapper.UnmapDirectory(config.Label); + this._mapper.UnmapDirectory(config.Label); } catch (MapperException ex) { - HandleMappingError(config, ex); + this.HandleMappingError(config, ex); } } } @@ -86,7 +86,7 @@ namespace winsw.Plugins.SharedDirectoryMapper { Logger.Error("Mapping of " + config.Label + " failed. STDOUT: " + ex.Process.StandardOutput.ReadToEnd() + " \r\nSTDERR: " + ex.Process.StandardError.ReadToEnd(), ex); - throw new ExtensionException(Descriptor.Id, DisplayName + ": Mapping of " + config.Label + "failed", ex); + throw new ExtensionException(this.Descriptor.Id, this.DisplayName + ": Mapping of " + config.Label + "failed", ex); } } } diff --git a/src/Plugins/SharedDirectoryMapper/SharedDirectoryMapperConfig.cs b/src/Plugins/SharedDirectoryMapper/SharedDirectoryMapperConfig.cs index ec532e1..273e207 100644 --- a/src/Plugins/SharedDirectoryMapper/SharedDirectoryMapperConfig.cs +++ b/src/Plugins/SharedDirectoryMapper/SharedDirectoryMapperConfig.cs @@ -1,7 +1,7 @@ using System.Xml; -using winsw.Util; +using WinSW.Util; -namespace winsw.Plugins.SharedDirectoryMapper +namespace WinSW.Plugins.SharedDirectoryMapper { /// /// Stores configuration entries for SharedDirectoryMapper extension. @@ -14,9 +14,9 @@ namespace winsw.Plugins.SharedDirectoryMapper public SharedDirectoryMapperConfig(bool enableMapping, string label, string uncPath) { - EnableMapping = enableMapping; - Label = label; - UNCPath = uncPath; + this.EnableMapping = enableMapping; + this.Label = label; + this.UNCPath = uncPath; } public static SharedDirectoryMapperConfig FromXml(XmlElement node) diff --git a/src/Plugins/SharedDirectoryMapper/SharedDirectoryMapperHelper.cs b/src/Plugins/SharedDirectoryMapper/SharedDirectoryMapperHelper.cs index 101f80d..1c4d05b 100644 --- a/src/Plugins/SharedDirectoryMapper/SharedDirectoryMapperHelper.cs +++ b/src/Plugins/SharedDirectoryMapper/SharedDirectoryMapperHelper.cs @@ -1,6 +1,6 @@ using System.Diagnostics; -namespace winsw.Plugins.SharedDirectoryMapper +namespace WinSW.Plugins.SharedDirectoryMapper { class SharedDirectoryMappingHelper { @@ -42,7 +42,7 @@ namespace winsw.Plugins.SharedDirectoryMapper /// Operation failure public void MapDirectory(string label, string uncPath) { - InvokeCommand("net.exe", " use " + label + " " + uncPath); + this.InvokeCommand("net.exe", " use " + label + " " + uncPath); } /// @@ -52,7 +52,7 @@ namespace winsw.Plugins.SharedDirectoryMapper /// Operation failure public void UnmapDirectory(string label) { - InvokeCommand("net.exe", " use /DELETE /YES " + label); + this.InvokeCommand("net.exe", " use /DELETE /YES " + label); } } @@ -64,8 +64,8 @@ namespace winsw.Plugins.SharedDirectoryMapper public MapperException(Process process, string command, string args) : base("Command " + command + " " + args + " failed with code " + process.ExitCode) { - Call = command + " " + args; - Process = process; + this.Call = command + " " + args; + this.Process = process; } } } diff --git a/src/Test/winswTests/Configuration/ExamplesTest.cs b/src/Test/winswTests/Configuration/ExamplesTest.cs index 8aa6dbc..4f8a12c 100644 --- a/src/Test/winswTests/Configuration/ExamplesTest.cs +++ b/src/Test/winswTests/Configuration/ExamplesTest.cs @@ -2,7 +2,7 @@ using System.Reflection; using System.Xml; using NUnit.Framework; -using winsw; +using WinSW; using winswTests.Util; namespace winswTests.Configuration diff --git a/src/Test/winswTests/DownloadConfigTests.cs b/src/Test/winswTests/DownloadConfigTests.cs index 54637bd..b066a18 100644 --- a/src/Test/winswTests/DownloadConfigTests.cs +++ b/src/Test/winswTests/DownloadConfigTests.cs @@ -1,6 +1,6 @@ using System.IO; using NUnit.Framework; -using winsw; +using WinSW; using winswTests.Util; namespace winswTests @@ -19,11 +19,11 @@ namespace winswTests var sd = ConfigXmlBuilder.create() .WithDownload(d) .ToServiceDescriptor(true); - var loaded = GetSingleEntry(sd); + var loaded = this.GetSingleEntry(sd); // Check default values Assert.That(loaded.FailOnError, Is.False); - Assert.That(loaded.Auth, Is.EqualTo(Download.AuthType.none)); + Assert.That(loaded.Auth, Is.EqualTo(Download.AuthType.None)); Assert.That(loaded.Username, Is.Null); Assert.That(loaded.Password, Is.Null); Assert.That(loaded.UnsecureAuth, Is.False); @@ -33,15 +33,15 @@ namespace winswTests public void Roundtrip_BasicAuth() { // Roundtrip data - Download d = new Download(From, To, true, Download.AuthType.basic, "aUser", "aPassword", true); + Download d = new Download(From, To, true, Download.AuthType.Basic, "aUser", "aPassword", true); var sd = ConfigXmlBuilder.create() .WithDownload(d) .ToServiceDescriptor(true); - var loaded = GetSingleEntry(sd); + var loaded = this.GetSingleEntry(sd); // Check default values Assert.That(loaded.FailOnError, Is.True); - Assert.That(loaded.Auth, Is.EqualTo(Download.AuthType.basic)); + Assert.That(loaded.Auth, Is.EqualTo(Download.AuthType.Basic)); Assert.That(loaded.Username, Is.EqualTo("aUser")); Assert.That(loaded.Password, Is.EqualTo("aPassword")); Assert.That(loaded.UnsecureAuth, Is.True); @@ -51,15 +51,15 @@ namespace winswTests public void Roundtrip_SSPI() { // Roundtrip data - Download d = new Download(From, To, false, Download.AuthType.sspi); + Download d = new Download(From, To, false, Download.AuthType.Sspi); var sd = ConfigXmlBuilder.create() .WithDownload(d) .ToServiceDescriptor(true); - var loaded = GetSingleEntry(sd); + var loaded = this.GetSingleEntry(sd); // Check default values Assert.That(loaded.FailOnError, Is.False); - Assert.That(loaded.Auth, Is.EqualTo(Download.AuthType.sspi)); + Assert.That(loaded.Auth, Is.EqualTo(Download.AuthType.Sspi)); Assert.That(loaded.Username, Is.Null); Assert.That(loaded.Password, Is.Null); Assert.That(loaded.UnsecureAuth, Is.False); @@ -73,22 +73,22 @@ namespace winswTests public void RejectBasicAuth_With_UnsecureProtocol(string protocolPrefix) { string unsecureFrom = protocolPrefix + "myServer.com:8080/file.txt"; - var d = new Download(unsecureFrom, To, auth: Download.AuthType.basic, username: "aUser", password: "aPassword"); - AssertInitializationFails(d, "Warning: you're sending your credentials in clear text to the server"); + var d = new Download(unsecureFrom, To, auth: Download.AuthType.Basic, username: "aUser", password: "aPassword"); + this.AssertInitializationFails(d, "Warning: you're sending your credentials in clear text to the server"); } [Test] public void RejectBasicAuth_Without_Username() { - var d = new Download(From, To, auth: Download.AuthType.basic, username: null, password: "aPassword"); - AssertInitializationFails(d, "Basic Auth is enabled, but username is not specified"); + var d = new Download(From, To, auth: Download.AuthType.Basic, username: null, password: "aPassword"); + this.AssertInitializationFails(d, "Basic Auth is enabled, but username is not specified"); } [Test] public void RejectBasicAuth_Without_Password() { - var d = new Download(From, To, auth: Download.AuthType.basic, username: "aUser", password: null); - AssertInitializationFails(d, "Basic Auth is enabled, but password is not specified"); + var d = new Download(From, To, auth: Download.AuthType.Basic, username: "aUser", password: null); + this.AssertInitializationFails(d, "Basic Auth is enabled, but password is not specified"); } /// @@ -104,7 +104,7 @@ namespace winswTests .WithDownload(d) .ToServiceDescriptor(true); - var loaded = GetSingleEntry(sd); + var loaded = this.GetSingleEntry(sd); Assert.That(loaded.From, Is.EqualTo(From)); Assert.That(loaded.To, Is.EqualTo(To)); Assert.That(loaded.FailOnError, Is.EqualTo(failOnError), "Unexpected FailOnError value"); @@ -120,7 +120,7 @@ namespace winswTests .WithRawEntry("") .ToServiceDescriptor(true); - var loaded = GetSingleEntry(sd); + var loaded = this.GetSingleEntry(sd); Assert.That(loaded.FailOnError, Is.False); } @@ -133,8 +133,8 @@ namespace winswTests var sd = ConfigXmlBuilder.create() .WithRawEntry("") .ToServiceDescriptor(true); - var loaded = GetSingleEntry(sd); - Assert.That(loaded.Auth, Is.EqualTo(Download.AuthType.sspi)); + var loaded = this.GetSingleEntry(sd); + Assert.That(loaded.Auth, Is.EqualTo(Download.AuthType.Sspi)); } [Test] @@ -145,7 +145,7 @@ namespace winswTests .WithRawEntry("") .ToServiceDescriptor(true); - Assert.That(() => GetSingleEntry(sd), Throws.TypeOf().With.Message.StartsWith("Cannot parse Enum value from string 'digest'")); + Assert.That(() => this.GetSingleEntry(sd), Throws.TypeOf().With.Message.StartsWith("Cannot parse Enum value from string 'digest'")); } [TestCase("http://", "127.0.0.1:80", "egarcia", "Passw0rd")] @@ -190,7 +190,7 @@ namespace winswTests .WithDownload(download) .ToServiceDescriptor(true); - Assert.That(() => GetSingleEntry(sd), Throws.TypeOf().With.Message.StartsWith(expectedMessagePart)); + Assert.That(() => this.GetSingleEntry(sd), Throws.TypeOf().With.Message.StartsWith(expectedMessagePart)); } } } diff --git a/src/Test/winswTests/DownloadTests.cs b/src/Test/winswTests/DownloadTests.cs index d5bf118..5c329bd 100644 --- a/src/Test/winswTests/DownloadTests.cs +++ b/src/Test/winswTests/DownloadTests.cs @@ -6,7 +6,7 @@ using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Threading.Tasks; using NUnit.Framework; -using winsw; +using WinSW; using winswTests.Util; namespace winswTests @@ -111,7 +111,7 @@ namespace winswTests await this.TestClientServerAsync( async (source, dest) => { - await new Download(source, dest, false, Download.AuthType.none).PerformAsync(); + await new Download(source, dest, false, Download.AuthType.None).PerformAsync(); Assert.That(File.ReadAllBytes(dest), Is.EqualTo(this.contents)); }, context => @@ -136,7 +136,7 @@ namespace winswTests await this.TestClientServerAsync( async (source, dest) => { - await new Download(source, dest, false, Download.AuthType.basic, username, password, true).PerformAsync(); + await new Download(source, dest, false, Download.AuthType.Basic, username, password, true).PerformAsync(); Assert.That(File.ReadAllBytes(dest), Is.EqualTo(this.contents)); }, context => diff --git a/src/Test/winswTests/Extensions/RunawayProcessKillerTest.cs b/src/Test/winswTests/Extensions/RunawayProcessKillerTest.cs index 007cf67..b92bcfb 100644 --- a/src/Test/winswTests/Extensions/RunawayProcessKillerTest.cs +++ b/src/Test/winswTests/Extensions/RunawayProcessKillerTest.cs @@ -3,10 +3,10 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using NUnit.Framework; -using winsw; -using winsw.Extensions; -using winsw.Plugins.RunawayProcessKiller; -using winsw.Util; +using WinSW; +using WinSW.Extensions; +using WinSW.Plugins.RunawayProcessKiller; +using WinSW.Util; using winswTests.Util; namespace winswTests.Extensions @@ -30,20 +30,20 @@ $@" -Xrs -jar \""%BASE%\slave.jar\"" -jnlpUrl ... - + foo/bar/pid.txt 5000 true "; - _testServiceDescriptor = ServiceDescriptor.FromXML(seedXml); + this._testServiceDescriptor = ServiceDescriptor.FromXML(seedXml); } [Test] public void LoadExtensions() { - WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor); + WinSWExtensionManager manager = new WinSWExtensionManager(this._testServiceDescriptor); manager.LoadExtensions(); Assert.AreEqual(1, manager.Extensions.Count, "One extension should be loaded"); @@ -58,7 +58,7 @@ $@" [Test] public void StartStopExtension() { - WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor); + WinSWExtensionManager manager = new WinSWExtensionManager(this._testServiceDescriptor); manager.LoadExtensions(); manager.FireOnWrapperStarted(); manager.FireBeforeWrapperStopped(); @@ -80,7 +80,7 @@ $@" ps.Arguments = "/c pause"; ps.UseShellExecute = false; ps.RedirectStandardOutput = true; - ps.EnvironmentVariables[WinSWSystem.ENVVAR_NAME_SERVICE_ID] = winswId; + ps.EnvironmentVariables[WinSWSystem.EnvVarNameServiceId] = winswId; proc.Start(); try diff --git a/src/Test/winswTests/Extensions/SharedDirectoryMapperTest.cs b/src/Test/winswTests/Extensions/SharedDirectoryMapperTest.cs index 28b227e..e0217a4 100644 --- a/src/Test/winswTests/Extensions/SharedDirectoryMapperTest.cs +++ b/src/Test/winswTests/Extensions/SharedDirectoryMapperTest.cs @@ -1,7 +1,7 @@ using NUnit.Framework; -using winsw; -using winsw.Extensions; -using winsw.Plugins.SharedDirectoryMapper; +using WinSW; +using WinSW.Extensions; +using WinSW.Plugins.SharedDirectoryMapper; namespace winswTests.Extensions { @@ -24,13 +24,13 @@ $@" -Xrs -jar \""%BASE%\slave.jar\"" -jnlpUrl ... - + - + @@ -38,13 +38,13 @@ $@" "; - _testServiceDescriptor = ServiceDescriptor.FromXML(seedXml); + this._testServiceDescriptor = ServiceDescriptor.FromXML(seedXml); } [Test] public void LoadExtensions() { - WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor); + WinSWExtensionManager manager = new WinSWExtensionManager(this._testServiceDescriptor); manager.LoadExtensions(); Assert.AreEqual(2, manager.Extensions.Count, "Two extensions should be loaded"); } @@ -52,7 +52,7 @@ $@" [Test] public void StartStopExtension() { - WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor); + WinSWExtensionManager manager = new WinSWExtensionManager(this._testServiceDescriptor); manager.LoadExtensions(); manager.FireOnWrapperStarted(); manager.FireBeforeWrapperStopped(); diff --git a/src/Test/winswTests/MainTest.cs b/src/Test/winswTests/MainTest.cs index e434e3b..c87b648 100644 --- a/src/Test/winswTests/MainTest.cs +++ b/src/Test/winswTests/MainTest.cs @@ -1,7 +1,7 @@ using System; using System.ServiceProcess; using NUnit.Framework; -using winsw; +using WinSW; using winswTests.Util; namespace winswTests diff --git a/src/Test/winswTests/ServiceDescriptorTests.cs b/src/Test/winswTests/ServiceDescriptorTests.cs index aacfd17..77580f9 100644 --- a/src/Test/winswTests/ServiceDescriptorTests.cs +++ b/src/Test/winswTests/ServiceDescriptorTests.cs @@ -1,7 +1,7 @@ using System; using System.Diagnostics; using NUnit.Framework; -using winsw; +using WinSW; using winswTests.Util; using WMI; @@ -38,13 +38,13 @@ $@" {ExpectedWorkingDirectory} C:\logs "; - _extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml); + this._extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml); } [Test] public void DefaultStartMode() { - Assert.That(_extendedServiceDescriptor.StartMode, Is.EqualTo(StartMode.Automatic)); + Assert.That(this._extendedServiceDescriptor.StartMode, Is.EqualTo(StartMode.Automatic)); } [Test] @@ -69,8 +69,8 @@ $@" C:\logs "; - _extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml); - Assert.That(() => _extendedServiceDescriptor.StartMode, Throws.ArgumentException); + this._extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml); + Assert.That(() => this._extendedServiceDescriptor.StartMode, Throws.ArgumentException); } [Test] @@ -95,35 +95,35 @@ $@" C:\logs "; - _extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml); - Assert.That(_extendedServiceDescriptor.StartMode, Is.EqualTo(StartMode.Manual)); + this._extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml); + Assert.That(this._extendedServiceDescriptor.StartMode, Is.EqualTo(StartMode.Manual)); } [Test] public void VerifyWorkingDirectory() { - Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory); - Assert.That(_extendedServiceDescriptor.WorkingDirectory, Is.EqualTo(ExpectedWorkingDirectory)); + Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + this._extendedServiceDescriptor.WorkingDirectory); + Assert.That(this._extendedServiceDescriptor.WorkingDirectory, Is.EqualTo(ExpectedWorkingDirectory)); } [Test] public void VerifyServiceLogonRight() { - Assert.That(_extendedServiceDescriptor.AllowServiceAcountLogonRight, Is.True); + Assert.That(this._extendedServiceDescriptor.AllowServiceAcountLogonRight, Is.True); } [Test] public void VerifyUsername() { - Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory); - Assert.That(_extendedServiceDescriptor.ServiceAccountUser, Is.EqualTo(Domain + "\\" + Username)); + Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + this._extendedServiceDescriptor.WorkingDirectory); + Assert.That(this._extendedServiceDescriptor.ServiceAccountUser, Is.EqualTo(Domain + "\\" + Username)); } [Test] public void VerifyPassword() { - Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory); - Assert.That(_extendedServiceDescriptor.ServiceAccountPassword, Is.EqualTo(Password)); + Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + this._extendedServiceDescriptor.WorkingDirectory); + Assert.That(this._extendedServiceDescriptor.ServiceAccountPassword, Is.EqualTo(Password)); } [Test] @@ -142,7 +142,7 @@ $@" [Test] public void StopParentProcessFirstIsFalseByDefault() { - Assert.That(_extendedServiceDescriptor.StopParentProcessFirst, Is.False); + Assert.That(this._extendedServiceDescriptor.StopParentProcessFirst, Is.False); } [Test] diff --git a/src/Test/winswTests/Util/CLITestHelper.cs b/src/Test/winswTests/Util/CLITestHelper.cs index a338f7b..186e6f4 100644 --- a/src/Test/winswTests/Util/CLITestHelper.cs +++ b/src/Test/winswTests/Util/CLITestHelper.cs @@ -1,7 +1,7 @@ using System; using System.IO; using NUnit.Framework; -using winsw; +using WinSW; namespace winswTests.Util { @@ -115,13 +115,13 @@ $@" public Exception Exception { get; } - public bool HasException => Exception != null; + public bool HasException => this.Exception != null; public CLITestResult(string output, string error, Exception exception = null) { - Out = output; - Error = error; - Exception = exception; + this.Out = output; + this.Error = error; + this.Exception = exception; } } } diff --git a/src/Test/winswTests/Util/ConfigXmlBuilder.cs b/src/Test/winswTests/Util/ConfigXmlBuilder.cs index dd926a0..e8e974a 100644 --- a/src/Test/winswTests/Util/ConfigXmlBuilder.cs +++ b/src/Test/winswTests/Util/ConfigXmlBuilder.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Text; -using winsw; -using winsw.Plugins.RunawayProcessKiller; +using WinSW; +using WinSW.Plugins.RunawayProcessKiller; using winswTests.Extensions; namespace winswTests.Util @@ -25,8 +25,8 @@ namespace winswTests.Util // TODO: Switch to the initializer? private ConfigXmlBuilder() { - configEntries = new List(); - ExtensionXmls = new List(); + this.configEntries = new List(); + this.ExtensionXmls = new List(); } public static ConfigXmlBuilder create(string id = null, string name = null, @@ -48,33 +48,33 @@ namespace winswTests.Util public string ToXMLString(bool dumpConfig = false) { StringBuilder str = new StringBuilder(); - if (PrintXMLVersion) + if (this.PrintXMLVersion) { // TODO: The encoding is generally wrong str.Append("\n"); } - if (XMLComment != null) + if (this.XMLComment != null) { - str.AppendFormat("\n", XMLComment); + str.AppendFormat("\n", this.XMLComment); } str.Append("\n"); - str.AppendFormat(" {0}\n", Id); - str.AppendFormat(" {0}\n", Name); - str.AppendFormat(" {0}\n", Description); - str.AppendFormat(" {0}\n", Executable); - foreach (string entry in configEntries) + str.AppendFormat(" {0}\n", this.Id); + str.AppendFormat(" {0}\n", this.Name); + str.AppendFormat(" {0}\n", this.Description); + str.AppendFormat(" {0}\n", this.Executable); + foreach (string entry in this.configEntries) { // We do not care much about pretty formatting here str.AppendFormat(" {0}\n", entry); } // Extensions - if (ExtensionXmls.Count > 0) + if (this.ExtensionXmls.Count > 0) { str.Append(" \n"); - foreach (string xml in ExtensionXmls) + foreach (string xml in this.ExtensionXmls) { str.Append(xml); } @@ -95,18 +95,18 @@ namespace winswTests.Util public ServiceDescriptor ToServiceDescriptor(bool dumpConfig = false) { - return ServiceDescriptor.FromXML(ToXMLString(dumpConfig)); + return ServiceDescriptor.FromXML(this.ToXMLString(dumpConfig)); } public ConfigXmlBuilder WithRawEntry(string entry) { - configEntries.Add(entry); + this.configEntries.Add(entry); return this; } public ConfigXmlBuilder WithTag(string tagName, string value) { - return WithRawEntry(string.Format("<{0}>{1}", tagName, value)); + return this.WithRawEntry(string.Format("<{0}>{1}", tagName, value)); } public ConfigXmlBuilder WithRunawayProcessKiller(RunawayProcessKillerExtension ext, string extensionId = "killRunawayProcess", bool enabled = true) @@ -119,7 +119,7 @@ namespace winswTests.Util str.AppendFormat(" {0}\n", ext.StopParentProcessFirst); str.AppendFormat(" {0}\n", ext.CheckWinSWEnvironmentVariable); str.Append(" \n"); - ExtensionXmls.Add(str.ToString()); + this.ExtensionXmls.Add(str.ToString()); return this; } @@ -130,10 +130,10 @@ namespace winswTests.Util xml.Append($""); - return WithRawEntry(xml.ToString()); + return this.WithRawEntry(xml.ToString()); } public ConfigXmlBuilder WithDelayedAutoStart() { - return WithRawEntry(""); + return this.WithRawEntry(""); } } } diff --git a/src/Test/winswTests/Util/ProcessHelperTest.cs b/src/Test/winswTests/Util/ProcessHelperTest.cs index 33e8197..776423a 100644 --- a/src/Test/winswTests/Util/ProcessHelperTest.cs +++ b/src/Test/winswTests/Util/ProcessHelperTest.cs @@ -3,7 +3,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using NUnit.Framework; -using winsw.Util; +using WinSW.Util; namespace winswTests.Util { diff --git a/src/Test/winswTests/Util/ServiceDescriptorAssert.cs b/src/Test/winswTests/Util/ServiceDescriptorAssert.cs index 86e94a6..37b1a11 100644 --- a/src/Test/winswTests/Util/ServiceDescriptorAssert.cs +++ b/src/Test/winswTests/Util/ServiceDescriptorAssert.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; using System.Reflection; using NUnit.Framework; -using winsw; -using winsw.Configuration; +using WinSW; +using WinSW.Configuration; namespace winswTests.Util { diff --git a/src/Test/winswTests/Util/TestHelper.cs b/src/Test/winswTests/Util/TestHelper.cs index f1a806e..8670721 100644 --- a/src/Test/winswTests/Util/TestHelper.cs +++ b/src/Test/winswTests/Util/TestHelper.cs @@ -1,5 +1,5 @@ using NUnit.Framework; -using winsw; +using WinSW; namespace winswTests.Util { diff --git a/src/stylecop.json b/src/stylecop.json new file mode 100644 index 0000000..5b778b3 --- /dev/null +++ b/src/stylecop.json @@ -0,0 +1,7 @@ +{ + "settings": { + "orderingRules": { + "usingDirectivesPlacement": "outsideNamespace" + } + } +} diff --git a/src/winsw.sln b/src/winsw.sln index b4e6aa8..3aba401 100644 --- a/src/winsw.sln +++ b/src/winsw.sln @@ -20,6 +20,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RunawayProcessKiller", "Plu EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{AA414F46-B863-473A-A0E0-C2971B3396AE}" ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig ..\examples\sample-allOptions.xml = ..\examples\sample-allOptions.xml ..\examples\sample-minimal.xml = ..\examples\sample-minimal.xml EndProjectSection diff --git a/src/winsw.sln.DotSettings b/src/winsw.sln.DotSettings deleted file mode 100644 index 45d451a..0000000 --- a/src/winsw.sln.DotSettings +++ /dev/null @@ -1,3 +0,0 @@ - - SW - UNC \ No newline at end of file