Browse Source

Merge shared directory mapping into core

NextTurn 5 years ago
parent
commit
3c5d67e287

+ 4 - 2
src/WinSW.Core/Configuration/ServiceConfig.cs

@@ -77,13 +77,15 @@ namespace WinSW.Configuration
         public virtual string ErrFilePattern => ".err.log";
 
         // Environment
-        public virtual List<Download> Downloads => new List<Download>(0);
+        public virtual List<Download> Downloads => new(0);
 
-        public virtual Dictionary<string, string> EnvironmentVariables => new Dictionary<string, string>(0);
+        public virtual Dictionary<string, string> EnvironmentVariables => new(0);
 
         // Misc
         public virtual bool BeepOnShutdown => false;
 
+        public virtual List<SharedDirectoryMapperConfig> SharedDirectories => new(0);
+
         // Extensions
         public virtual XmlNode? ExtensionsConfiguration => null;
     }

+ 27 - 2
src/WinSW.Core/Configuration/XmlServiceConfig.cs

@@ -18,7 +18,7 @@ namespace WinSW
     /// </summary>
     public class XmlServiceConfig : ServiceConfig
     {
-        protected readonly XmlDocument dom = new XmlDocument();
+        protected readonly XmlDocument dom = new();
 
         private readonly XmlNode root;
         private readonly Dictionary<string, string> environmentVariables;
@@ -145,7 +145,7 @@ namespace WinSW
             return value is null ? defaultValue : ParseTimeSpan(value);
         }
 
-        private static readonly Dictionary<string, long> Suffix = new Dictionary<string, long>
+        private static readonly Dictionary<string, long> Suffix = new()
         {
             { "ms",     1 },
             { "sec",    1000L },
@@ -581,6 +581,31 @@ namespace WinSW
 
         public bool AutoRefresh => this.SingleBoolElementOrDefault("autoRefresh", true);
 
+        public override List<SharedDirectoryMapperConfig> SharedDirectories
+        {
+            get
+            {
+                var mapNodes = this.root.SelectSingleNode("sharedDirectoryMapping")?.SelectNodes("map");
+                if (mapNodes is null)
+                {
+                    return new();
+                }
+
+                var result = new List<SharedDirectoryMapperConfig>(mapNodes.Count);
+                for (int i = 0; i < mapNodes.Count; i++)
+                {
+                    if (mapNodes[i] is XmlElement mapElement)
+                    {
+                        string label = XmlHelper.SingleAttribute<string>(mapElement, "label");
+                        string uncPath = XmlHelper.SingleAttribute<string>(mapElement, "uncpath");
+                        result.Add(new(label, uncPath));
+                    }
+                }
+
+                return result;
+            }
+        }
+
         private Dictionary<string, string> LoadEnvironmentVariables()
         {
             var nodeList = this.root.SelectNodes("env")!;

+ 1 - 1
src/WinSW.Core/LogAppenders.cs

@@ -419,7 +419,7 @@ namespace WinSW
         private async Task CopyStreamWithRotationAsync(StreamReader reader, string extension)
         {
             // 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
-            object? fileLock = new object();
+            object? fileLock = new();
 
             string? baseDirectory = Path.GetDirectoryName(this.BaseLogFileName)!;
             string? baseFileName = Path.GetFileName(this.BaseLogFileName);

+ 0 - 0
src/WinSW/Logging/IServiceEventLog.cs → src/WinSW.Core/Logging/IServiceEventLog.cs


+ 0 - 0
src/WinSW/Logging/WrapperServiceEventLogProvider.cs → src/WinSW.Core/Logging/WrapperServiceEventLogProvider.cs


+ 1 - 0
src/WinSW.Core/Native/Libraries.cs

@@ -5,6 +5,7 @@
         internal const string Advapi32 = "advapi32.dll";
         internal const string CredUI = "credui.dll";
         internal const string Kernel32 = "kernel32.dll";
+        internal const string Mpr = "mpr.dll";
         internal const string NtDll = "ntdll.dll";
     }
 }

+ 31 - 0
src/WinSW.Core/Native/NetworkApis.cs

@@ -0,0 +1,31 @@
+#pragma warning disable SA1310 // Field names should not contain underscore
+
+using System.Runtime.InteropServices;
+using static WinSW.Native.Libraries;
+
+namespace WinSW.Native
+{
+    internal static class NetworkApis
+    {
+        internal const uint RESOURCETYPE_DISK = 0x00000001;
+
+        [DllImport(Mpr, SetLastError = true, CharSet = CharSet.Unicode)]
+        internal static extern int WNetAddConnection2W(in NETRESOURCEW netResource, string? password = null, string? userName = null, uint flags = 0);
+
+        [DllImport(Mpr, SetLastError = true, CharSet = CharSet.Unicode)]
+        internal static extern int WNetCancelConnection2W(string name, uint flags = 0, bool force = false);
+
+        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+        internal struct NETRESOURCEW
+        {
+            public uint Scope;
+            public uint Type;
+            public uint DisplayType;
+            public uint Usage;
+            public string LocalName;
+            public string RemoteName;
+            public string Comment;
+            public string Provider;
+        }
+    }
+}

+ 2 - 2
src/WinSW.Core/Native/ResourceApis.cs

@@ -7,9 +7,9 @@ namespace WinSW.Native
 {
     internal static class ResourceApis
     {
-        internal static readonly IntPtr VS_VERSION_INFO = new IntPtr(1);
+        internal static readonly IntPtr VS_VERSION_INFO = new(1);
 
-        internal static readonly IntPtr RT_VERSION = new IntPtr(16);
+        internal static readonly IntPtr RT_VERSION = new(16);
 
         [DllImport(Libraries.Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
         internal static extern IntPtr BeginUpdateResourceW(string fileName, bool deleteExistingResources);

+ 0 - 0
src/WinSW/ServiceMessages.cs → src/WinSW.Core/ServiceMessages.cs


+ 50 - 0
src/WinSW.Core/SharedDirectoryMapper.cs

@@ -0,0 +1,50 @@
+using System.Collections.Generic;
+using WinSW.Native;
+using static WinSW.Native.NetworkApis;
+
+namespace WinSW
+{
+    public sealed class SharedDirectoryMapper
+    {
+        private readonly List<SharedDirectoryMapperConfig> entries;
+
+        public SharedDirectoryMapper(List<SharedDirectoryMapperConfig> entries)
+        {
+            this.entries = entries;
+        }
+
+        public void Map()
+        {
+            foreach (var config in this.entries)
+            {
+                string label = config.Label;
+                string uncPath = config.UncPath;
+
+                int error = WNetAddConnection2W(new()
+                {
+                    Type = RESOURCETYPE_DISK,
+                    LocalName = label,
+                    RemoteName = uncPath,
+                });
+                if (error != 0)
+                {
+                    Throw.Command.Win32Exception(error, $"Failed to map {label}.");
+                }
+            }
+        }
+
+        public void Unmap()
+        {
+            foreach (var config in this.entries)
+            {
+                string label = config.Label;
+
+                int error = WNetCancelConnection2W(label);
+                if (error != 0)
+                {
+                    Throw.Command.Win32Exception(error, $"Failed to unmap {label}.");
+                }
+            }
+        }
+    }
+}

+ 15 - 0
src/WinSW.Core/SharedDirectoryMapperConfig.cs

@@ -0,0 +1,15 @@
+namespace WinSW
+{
+    public sealed class SharedDirectoryMapperConfig
+    {
+        public string Label { get; }
+
+        public string UncPath { get; }
+
+        public SharedDirectoryMapperConfig(string driveLabel, string directoryUncPath)
+        {
+            this.Label = driveLabel;
+            this.UncPath = directoryUncPath;
+        }
+    }
+}

+ 29 - 11
src/WinSW/WrapperService.cs → src/WinSW.Core/WrapperService.cs

@@ -17,9 +17,9 @@ namespace WinSW
 {
     public sealed class WrapperService : ServiceBase, IEventLogger, IServiceEventLog
     {
-        internal static readonly WrapperServiceEventLogProvider eventLogProvider = new WrapperServiceEventLogProvider();
+        internal static readonly WrapperServiceEventLogProvider EventLogProvider = new();
 
-        private static readonly int additionalStopTimeout = 1_000;
+        private static readonly int AdditionalStopTimeout = 1_000;
 
         private static readonly ILog Log = LogManager.GetLogger(typeof(WrapperService));
 
@@ -31,6 +31,8 @@ namespace WinSW
 
         internal WinSWExtensionManager ExtensionManager { get; }
 
+        private SharedDirectoryMapper? sharedDirectoryMapper;
+
         private bool shuttingdown;
 
         /// <summary>
@@ -51,7 +53,7 @@ namespace WinSW
             this.ExtensionManager = new WinSWExtensionManager(config);
 
             // Register the event log provider
-            eventLogProvider.Service = this;
+            EventLogProvider.Service = this;
 
             if (config.Preshutdown)
             {
@@ -297,6 +299,13 @@ namespace WinSW
                 throw new AggregateException(exceptions);
             }
 
+            var sharedDirectories = this.config.SharedDirectories;
+            if (sharedDirectories.Count > 0)
+            {
+                this.sharedDirectoryMapper = new(sharedDirectories);
+                this.sharedDirectoryMapper.Map();
+            }
+
             var prestart = this.config.Prestart;
             string? prestartExecutable = prestart.Executable;
             if (prestartExecutable != null)
@@ -306,7 +315,7 @@ namespace WinSW
                     using var process = this.StartProcess(prestartExecutable, prestart.Arguments, prestart.CreateLogHandler());
                     this.WaitForProcessToExit(process);
                     this.LogExited($"Pre-start process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
-                    process.StopDescendants(additionalStopTimeout);
+                    process.StopDescendants(AdditionalStopTimeout);
                 }
                 catch (Exception e)
                 {
@@ -335,7 +344,7 @@ namespace WinSW
                     using var process = StartProcessLocked();
                     this.WaitForProcessToExit(process);
                     this.LogExited($"Post-start process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
-                    process.StopDescendants(additionalStopTimeout);
+                    process.StopDescendants(AdditionalStopTimeout);
                     this.startingProcess = null;
 
                     Process StartProcessLocked()
@@ -367,7 +376,7 @@ namespace WinSW
                     using var process = StartProcessLocked(prestopExecutable, prestop.Arguments, prestop.CreateLogHandler());
                     this.WaitForProcessToExit(process);
                     this.LogExited($"Pre-stop process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
-                    process.StopDescendants(additionalStopTimeout);
+                    process.StopDescendants(AdditionalStopTimeout);
                     this.stoppingProcess = null;
                 }
                 catch (Exception e)
@@ -408,7 +417,7 @@ namespace WinSW
 
                     Log.Debug("WaitForProcessToExit " + this.process.Id + "+" + stopProcess.Id);
                     this.WaitForProcessToExit(stopProcess);
-                    stopProcess.StopDescendants(additionalStopTimeout);
+                    stopProcess.StopDescendants(AdditionalStopTimeout);
                     this.stoppingProcess = null;
 
                     this.WaitForProcessToExit(this.process);
@@ -429,8 +438,8 @@ namespace WinSW
                 {
                     using var process = StartProcessLocked(poststopExecutable, poststop.Arguments, poststop.CreateLogHandler());
                     this.WaitForProcessToExit(process);
-                    this.LogExited($"Post-Stop process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
-                    process.StopDescendants(additionalStopTimeout);
+                    this.LogExited($"Post-stop process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
+                    process.StopDescendants(AdditionalStopTimeout);
                     this.stoppingProcess = null;
                 }
                 catch (Exception e)
@@ -439,6 +448,15 @@ namespace WinSW
                 }
             }
 
+            try
+            {
+                this.sharedDirectoryMapper?.Unmap();
+            }
+            catch (Exception e)
+            {
+                Log.Error(e);
+            }
+
             // Stop extensions
             this.ExtensionManager.FireBeforeWrapperStopped();
 
@@ -513,8 +531,8 @@ namespace WinSW
 
                     process.StopDescendants(this.config.StopTimeoutInMs);
 
-                    this.startingProcess?.StopTree(additionalStopTimeout);
-                    this.stoppingProcess?.StopTree(additionalStopTimeout);
+                    this.startingProcess?.StopTree(AdditionalStopTimeout);
+                    this.stoppingProcess?.StopTree(AdditionalStopTimeout);
 
                     // if we finished orderly, report that to SCM.
                     // by not reporting unclean shutdown, we let Windows SCM to decide if it wants to

+ 0 - 121
src/WinSW.Plugins/SharedDirectoryMapper.cs

@@ -1,121 +0,0 @@
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Runtime.InteropServices;
-using System.Xml;
-using log4net;
-using WinSW.Extensions;
-using WinSW.Util;
-using static WinSW.Plugins.SharedDirectoryMapper.SharedDirectoryMapper.Native;
-
-namespace WinSW.Plugins.SharedDirectoryMapper
-{
-    public class SharedDirectoryMapper : AbstractWinSWExtension
-    {
-        private readonly List<SharedDirectoryMapperConfig> entries = new List<SharedDirectoryMapperConfig>();
-
-        public override string DisplayName => "Shared Directory Mapper";
-
-        private static readonly ILog Logger = LogManager.GetLogger(typeof(SharedDirectoryMapper));
-
-        public SharedDirectoryMapper()
-        {
-        }
-
-        public SharedDirectoryMapper(bool enableMapping, string directoryUNC, string driveLabel)
-        {
-            var config = new SharedDirectoryMapperConfig(enableMapping, driveLabel, directoryUNC);
-            this.entries.Add(config);
-        }
-
-        public override void Configure(XmlServiceConfig config, XmlNode node)
-        {
-            var mapNodes = XmlHelper.SingleNode(node, "mapping", false)!.SelectNodes("map");
-            if (mapNodes != null)
-            {
-                for (int i = 0; i < mapNodes.Count; i++)
-                {
-                    if (mapNodes[i] is XmlElement mapElement)
-                    {
-                        this.entries.Add(SharedDirectoryMapperConfig.FromXml(mapElement));
-                    }
-                }
-            }
-        }
-
-        public override void OnWrapperStarted()
-        {
-            foreach (var config in this.entries)
-            {
-                string label = config.Label;
-                string uncPath = config.UNCPath;
-                if (config.EnableMapping)
-                {
-                    Logger.Info(this.DisplayName + ": Mapping shared directory " + uncPath + " to " + label);
-
-                    int error = WNetAddConnection2(new NETRESOURCE
-                    {
-                        Type = RESOURCETYPE_DISK,
-                        LocalName = label,
-                        RemoteName = uncPath,
-                    });
-                    if (error != 0)
-                    {
-                        this.ThrowExtensionException(error, $"Mapping of {label} failed.");
-                    }
-                }
-                else
-                {
-                    Logger.Warn(this.DisplayName + ": Mapping of " + label + " is disabled");
-                }
-            }
-        }
-
-        public override void BeforeWrapperStopped()
-        {
-            foreach (var config in this.entries)
-            {
-                string label = config.Label;
-                if (config.EnableMapping)
-                {
-                    int error = WNetCancelConnection2(label);
-                    if (error != 0)
-                    {
-                        this.ThrowExtensionException(error, $"Unmapping of {label} failed.");
-                    }
-                }
-            }
-        }
-
-        private void ThrowExtensionException(int error, string message)
-        {
-            var inner = new Win32Exception(error);
-            throw new ExtensionException(this.Descriptor.Id, $"{this.DisplayName}: {message} {inner.Message}", inner);
-        }
-
-        internal static class Native
-        {
-            internal const uint RESOURCETYPE_DISK = 0x00000001;
-
-            private const string MprLibraryName = "mpr.dll";
-
-            [DllImport(MprLibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "WNetAddConnection2W")]
-            internal static extern int WNetAddConnection2(in NETRESOURCE netResource, string? password = null, string? userName = null, uint flags = 0);
-
-            [DllImport(MprLibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "WNetCancelConnection2W")]
-            internal static extern int WNetCancelConnection2(string name, uint flags = 0, bool force = false);
-
-            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
-            internal struct NETRESOURCE
-            {
-                public uint Scope;
-                public uint Type;
-                public uint DisplayType;
-                public uint Usage;
-                public string LocalName;
-                public string RemoteName;
-                public string Comment;
-                public string Provider;
-            }
-        }
-    }
-}

+ 0 - 32
src/WinSW.Plugins/SharedDirectoryMapperConfig.cs

@@ -1,32 +0,0 @@
-using System.Xml;
-using WinSW.Util;
-
-namespace WinSW.Plugins.SharedDirectoryMapper
-{
-    /// <summary>
-    /// Stores configuration entries for SharedDirectoryMapper extension.
-    /// </summary>
-    public class SharedDirectoryMapperConfig
-    {
-        public bool EnableMapping { get; }
-
-        public string Label { get; }
-
-        public string UNCPath { get; }
-
-        public SharedDirectoryMapperConfig(bool enableMapping, string label, string uncPath)
-        {
-            this.EnableMapping = enableMapping;
-            this.Label = label;
-            this.UNCPath = uncPath;
-        }
-
-        public static SharedDirectoryMapperConfig FromXml(XmlElement node)
-        {
-            bool enableMapping = XmlHelper.SingleAttribute(node, "enabled", true);
-            string label = XmlHelper.SingleAttribute<string>(node, "label");
-            string uncPath = XmlHelper.SingleAttribute<string>(node, "uncpath");
-            return new SharedDirectoryMapperConfig(enableMapping, label, uncPath);
-        }
-    }
-}

+ 1 - 1
src/WinSW.Tests/DownloadTests.cs

@@ -11,7 +11,7 @@ namespace WinSW.Tests
 {
     public class DownloadTests : IDisposable
     {
-        private readonly HttpListener globalListener = new HttpListener();
+        private readonly HttpListener globalListener = new();
 
         private readonly byte[] contents = { 0x57, 0x69, 0x6e, 0x53, 0x57 };
 

+ 0 - 21
src/WinSW.Tests/Extensions/ExtensionTestBase.cs

@@ -1,21 +0,0 @@
-using System;
-
-namespace WinSW.Tests.Extensions
-{
-    /// <summary>
-    /// Base class for testing of WinSW Extensions.
-    /// </summary>
-    public class ExtensionTestBase
-    {
-        /// <summary>
-        /// Defines the name of the extension to be passed in the configuration.
-        /// This name should point to assembly in tests, because we do not merge extension DLLs for testing purposes.
-        /// </summary>
-        /// <param name="type">Type of the extension</param>
-        /// <returns>String for Type locator, which includes class and assembly names</returns>
-        public static string GetExtensionClassNameWithAssembly(Type type)
-        {
-            return type.ToString() + ", " + type.Assembly;
-        }
-    }
-}

+ 0 - 58
src/WinSW.Tests/Extensions/SharedDirectoryMapperConfigTest.cs

@@ -1,58 +0,0 @@
-using WinSW.Extensions;
-using WinSW.Plugins.SharedDirectoryMapper;
-using Xunit;
-
-namespace WinSW.Tests.Extensions
-{
-    public class SharedDirectoryMapperConfigTest : ExtensionTestBase
-    {
-        private readonly XmlServiceConfig serviceConfig;
-
-        private readonly string testExtension = GetExtensionClassNameWithAssembly(typeof(SharedDirectoryMapper));
-
-        public SharedDirectoryMapperConfigTest()
-        {
-            string seedXml =
-$@"<service>
-  <id>SERVICE_NAME</id>
-  <name>Jenkins Slave</name>
-  <description>This service runs a slave for Jenkins continuous integration system.</description>
-  <executable>C:\Program Files\Java\jre7\bin\java.exe</executable>
-  <arguments>-Xrs  -jar \""%BASE%\slave.jar\"" -jnlpUrl ...</arguments>
-  <log mode=""roll""></log>
-  <extensions>
-    <extension enabled=""true"" className=""{this.testExtension}"" id=""mapNetworDirs"">
-      <mapping>
-        <map enabled=""false"" label=""N:"" uncpath=""\\UNC""/>
-        <map enabled=""false"" label=""M:"" uncpath=""\\UNC2""/>
-      </mapping>
-    </extension>
-    <extension enabled=""true"" className=""{this.testExtension}"" id=""mapNetworDirs2"">
-      <mapping>
-        <map enabled=""false"" label=""X:"" uncpath=""\\UNC""/>
-        <map enabled=""false"" label=""Y:"" uncpath=""\\UNC2""/>
-      </mapping>
-    </extension>
-  </extensions>
-</service>";
-            this.serviceConfig = XmlServiceConfig.FromXml(seedXml);
-        }
-
-        [Fact]
-        public void LoadExtensions()
-        {
-            var manager = new WinSWExtensionManager(this.serviceConfig);
-            manager.LoadExtensions();
-            Assert.Equal(2, manager.Extensions.Count);
-        }
-
-        [Fact]
-        public void StartStopExtension()
-        {
-            var manager = new WinSWExtensionManager(this.serviceConfig);
-            manager.LoadExtensions();
-            manager.FireOnWrapperStarted();
-            manager.FireBeforeWrapperStopped();
-        }
-    }
-}

+ 21 - 0
src/WinSW.Tests/ServiceConfigTests.cs

@@ -420,5 +420,26 @@ $@"<service>
                 Assert.Equal(expected.StderrPath, actual.StderrPath);
             }
         }
+
+        [Fact]
+        public void SharedDirectoryMapping()
+        {
+            string seedXml =
+@"<service>
+  <sharedDirectoryMapping>
+    <map label=""N:"" uncpath=""\\UNC"" />
+    <map label=""M:"" uncpath=""\\UNC2"" />
+  </sharedDirectoryMapping>
+</service>";
+
+            var config = XmlServiceConfig.FromXml(seedXml);
+
+            var sharedDirectories = config.SharedDirectories;
+            Assert.Equal(2, sharedDirectories.Count);
+            Assert.Equal("N:", sharedDirectories[0].Label);
+            Assert.Equal(@"\\UNC", sharedDirectories[0].UncPath);
+            Assert.Equal("M:", sharedDirectories[1].Label);
+            Assert.Equal(@"\\UNC2", sharedDirectories[1].UncPath);
+        }
     }
 }

+ 16 - 23
src/WinSW.Tests/Extensions/SharedDirectoryMapperTests.cs → src/WinSW.Tests/SharedDirectoryMapperTests.cs

@@ -3,39 +3,32 @@ using System;
 using System.IO;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
-using WinSW.Plugins.SharedDirectoryMapper;
 using Xunit;
 
 namespace WinSW.Tests.Extensions
 {
-    // TODO: Assert.Throws<ExtensionException>
     public class SharedDirectoryMapperTests
     {
-        [ElevatedFact]
-        public void TestMap()
+        private static SharedDirectoryMapper CreateMapper(string driveLabel, string directoryUncPath)
         {
-            using var data = TestData.Create();
-
-            const string label = "W:";
-            var mapper = new SharedDirectoryMapper(true, $@"\\{Environment.MachineName}\{data.name}", label);
-
-            mapper.OnWrapperStarted();
-            Assert.True(Directory.Exists($@"{label}\"));
-            mapper.BeforeWrapperStopped();
-            Assert.False(Directory.Exists($@"{label}\"));
+            return new(new(1)
+            {
+                new(driveLabel, directoryUncPath),
+            });
         }
 
         [ElevatedFact]
-        public void TestDisableMapping()
+        public void TestMap()
         {
             using var data = TestData.Create();
 
             const string label = "W:";
-            var mapper = new SharedDirectoryMapper(enableMapping: false, $@"\\{Environment.MachineName}\{data.name}", label);
+            var mapper = CreateMapper(label, $@"\\{Environment.MachineName}\{data.name}");
 
-            mapper.OnWrapperStarted();
+            mapper.Map();
+            Assert.True(Directory.Exists($@"{label}\"));
+            mapper.Unmap();
             Assert.False(Directory.Exists($@"{label}\"));
-            mapper.BeforeWrapperStopped();
         }
 
         [ElevatedFact]
@@ -44,11 +37,11 @@ namespace WinSW.Tests.Extensions
             using var data = TestData.Create();
 
             const string label = "W:";
-            var mapper = new SharedDirectoryMapper(true, $@"\\{Environment.MachineName}\{data.name}\", label);
+            var mapper = CreateMapper(label, $@"\\{Environment.MachineName}\{data.name}\");
 
-            _ = Assert.ThrowsAny<Exception>(() => mapper.OnWrapperStarted());
+            _ = Assert.ThrowsAny<Exception>(() => mapper.Map());
             Assert.False(Directory.Exists($@"{label}\"));
-            _ = Assert.ThrowsAny<Exception>(() => mapper.BeforeWrapperStopped());
+            _ = Assert.ThrowsAny<Exception>(() => mapper.Unmap());
         }
 
         [ElevatedFact]
@@ -57,11 +50,11 @@ namespace WinSW.Tests.Extensions
             using var data = TestData.Create();
 
             const string label = "W";
-            var mapper = new SharedDirectoryMapper(true, $@"\\{Environment.MachineName}\{data.name}", label);
+            var mapper = CreateMapper(label, $@"\\{Environment.MachineName}\{data.name}");
 
-            _ = Assert.ThrowsAny<Exception>(() => mapper.OnWrapperStarted());
+            _ = Assert.ThrowsAny<Exception>(() => mapper.Map());
             Assert.False(Directory.Exists($@"{label}\"));
-            _ = Assert.ThrowsAny<Exception>(() => mapper.BeforeWrapperStopped());
+            _ = Assert.ThrowsAny<Exception>(() => mapper.Unmap());
         }
 
         private readonly ref struct TestData

+ 1 - 1
src/WinSW.Tests/Util/ConfigXmlBuilder.cs

@@ -23,7 +23,7 @@ namespace WinSW.Tests.Util
 
         public List<string> ExtensionXmls { get; } = new List<string>();
 
-        private readonly List<string> configEntries = new List<string>();
+        private readonly List<string> configEntries = new();
 
         private readonly ITestOutputHelper output;
 

+ 1 - 1
src/WinSW/Program.cs

@@ -1099,7 +1099,7 @@ namespace WinSW
             }
             else
             {
-                var eventLogAppender = new ServiceEventLogAppender(WrapperService.eventLogProvider)
+                var eventLogAppender = new ServiceEventLogAppender(WrapperService.EventLogProvider)
                 {
                     Name = "Wrapper event log",
                     Threshold = eventLogLevel,