mirror of https://github.com/winsw/winsw
				
				
				
			Decouple Default Settings to a separate publicly accessible class.
Required for tests.pull/170/head
							parent
							
								
									413e24ebeb
								
							
						
					
					
						commit
						14f32cd309
					
				| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using WMI;
 | 
			
		||||
 | 
			
		||||
namespace winsw.Configuration
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Default WinSW settings
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public sealed class DefaultWinSWSettings : IWinSWConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        public string Id { get { return null; } }
 | 
			
		||||
        public string Caption { get { return null; } }
 | 
			
		||||
        public string Description { get { return null; } }
 | 
			
		||||
        public string Executable { get { return null; } }
 | 
			
		||||
 | 
			
		||||
        public string ExecutablePath
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                // this returns the executable name as given by the calling process, so
 | 
			
		||||
                // it needs to be absolutized.
 | 
			
		||||
                string p = Environment.GetCommandLineArgs()[0];
 | 
			
		||||
                return Path.GetFullPath(p);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Installation
 | 
			
		||||
        public bool AllowServiceAcountLogonRight { get { return false; } }
 | 
			
		||||
        public string ServiceAccountPassword { get { return null; } }
 | 
			
		||||
        public string ServiceAccountUser { get { return null; } }
 | 
			
		||||
        public List<winsw.Native.SC_ACTION> FailureActions { get { return new List<winsw.Native.SC_ACTION>(); } }
 | 
			
		||||
        public TimeSpan ResetFailureAfter { get { return TimeSpan.FromDays(1); } }
 | 
			
		||||
 | 
			
		||||
        // Executable management
 | 
			
		||||
        public string Arguments { get { return ""; } }
 | 
			
		||||
        public string Startarguments { get { return null; } }
 | 
			
		||||
        public string StopExecutable { get { return null; } }
 | 
			
		||||
        public string Stoparguments { get { return null; } }
 | 
			
		||||
        public string WorkingDirectory { get { return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); } }
 | 
			
		||||
        public ProcessPriorityClass Priority { get { return ProcessPriorityClass.Normal; } }
 | 
			
		||||
        public TimeSpan StopTimeout { get { return TimeSpan.FromSeconds(15); } }
 | 
			
		||||
        public bool StopParentProcessFirst { get { return false; } }
 | 
			
		||||
 | 
			
		||||
        // Service management
 | 
			
		||||
        public StartMode StartMode { get { return StartMode.Automatic; } }
 | 
			
		||||
        public string[] ServiceDependencies { get { return new string[0]; } }
 | 
			
		||||
        public TimeSpan WaitHint { get { return TimeSpan.FromSeconds(15); } }
 | 
			
		||||
        public TimeSpan SleepTime { get { return TimeSpan.FromSeconds(1); } }
 | 
			
		||||
        public bool Interactive { get { return false; } }
 | 
			
		||||
 | 
			
		||||
        // Logging
 | 
			
		||||
        public string LogDirectory { get { return Path.GetDirectoryName(ExecutablePath); } }
 | 
			
		||||
        public string LogMode { get { return "append"; } }
 | 
			
		||||
 | 
			
		||||
        // Environment
 | 
			
		||||
        public List<Download> Downloads { get { return new List<Download>(); } }
 | 
			
		||||
        public Dictionary<string, string> EnvironmentVariables { get { return new Dictionary<string, string>(); } }
 | 
			
		||||
 | 
			
		||||
        // Misc
 | 
			
		||||
        public bool BeepOnShutdown { get { return false; } }
 | 
			
		||||
 | 
			
		||||
        // Extensions
 | 
			
		||||
        public XmlNode ExtensionsConfiguration { get {return null; } }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using WMI;
 | 
			
		||||
namespace winsw.Configuration
 | 
			
		||||
{
 | 
			
		||||
    interface IWinSWConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        //TODO: Document the parameters && refactor
 | 
			
		||||
 | 
			
		||||
        string Id { get; }
 | 
			
		||||
        string Caption { get; }
 | 
			
		||||
        string Description { get; }
 | 
			
		||||
        string Executable { get; }
 | 
			
		||||
        string ExecutablePath { get; }
 | 
			
		||||
 | 
			
		||||
        // Installation
 | 
			
		||||
        bool AllowServiceAcountLogonRight { get; }
 | 
			
		||||
        string ServiceAccountPassword { get; }
 | 
			
		||||
        string ServiceAccountUser { get; }
 | 
			
		||||
        List<winsw.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<Download> Downloads { get; }
 | 
			
		||||
        Dictionary<string, string> EnvironmentVariables { get; }
 | 
			
		||||
        
 | 
			
		||||
        // Misc
 | 
			
		||||
        bool BeepOnShutdown { get; }
 | 
			
		||||
 | 
			
		||||
        // Extensions
 | 
			
		||||
        XmlNode ExtensionsConfiguration { get; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ using System.Diagnostics;
 | 
			
		|||
using System.IO;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using winsw.Configuration;
 | 
			
		||||
using winsw.Native;
 | 
			
		||||
using winsw.Util;
 | 
			
		||||
using WMI;
 | 
			
		||||
| 
						 | 
				
			
			@ -14,17 +15,21 @@ namespace winsw
 | 
			
		|||
    /// <summary>
 | 
			
		||||
    /// In-memory representation of the configuration file.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class ServiceDescriptor
 | 
			
		||||
    public class ServiceDescriptor : IWinSWConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        // ReSharper disable once InconsistentNaming
 | 
			
		||||
        protected readonly XmlDocument dom = new XmlDocument();
 | 
			
		||||
 | 
			
		||||
        private static readonly DefaultWinSWSettings defaults = new DefaultWinSWSettings();
 | 
			
		||||
        public static DefaultWinSWSettings Defaults { get { return defaults; } }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Where did we find the configuration file?
 | 
			
		||||
        /// 
 | 
			
		||||
        /// This string is "c:\abc\def\ghi" when the configuration XML is "c:\abc\def\ghi.xml"
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string BasePath { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The file name portion of the configuration file.
 | 
			
		||||
        /// 
 | 
			
		||||
| 
						 | 
				
			
			@ -36,10 +41,8 @@ namespace winsw
 | 
			
		|||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                // this returns the executable name as given by the calling process, so
 | 
			
		||||
                // it needs to be absolutized.
 | 
			
		||||
                string p = Environment.GetCommandLineArgs()[0];
 | 
			
		||||
                return Path.GetFullPath(p);
 | 
			
		||||
                // Currently there is no opportunity to alter the executable path
 | 
			
		||||
                return Defaults.ExecutablePath;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -191,7 +194,7 @@ namespace winsw
 | 
			
		|||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                string arguments = AppendTags("argument");
 | 
			
		||||
                string arguments = AppendTags("argument", Defaults.Arguments);
 | 
			
		||||
 | 
			
		||||
                if (arguments == null)
 | 
			
		||||
                {
 | 
			
		||||
| 
						 | 
				
			
			@ -199,7 +202,7 @@ namespace winsw
 | 
			
		|||
 | 
			
		||||
                    if (argumentsNode == null)
 | 
			
		||||
                    {
 | 
			
		||||
                        return "";
 | 
			
		||||
                        return Defaults.Arguments;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return Environment.ExpandEnvironmentVariables(argumentsNode.InnerText);
 | 
			
		||||
| 
						 | 
				
			
			@ -218,7 +221,7 @@ namespace winsw
 | 
			
		|||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return AppendTags("startargument");
 | 
			
		||||
                return AppendTags("startargument", Defaults.Startarguments);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -229,7 +232,7 @@ namespace winsw
 | 
			
		|||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return AppendTags("stopargument");
 | 
			
		||||
                return AppendTags("stopargument", Defaults.Startarguments);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +240,7 @@ namespace winsw
 | 
			
		|||
        public string WorkingDirectory {
 | 
			
		||||
            get {
 | 
			
		||||
                var wd = SingleElement("workingdirectory", true);
 | 
			
		||||
                return String.IsNullOrEmpty(wd) ? Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) : wd;
 | 
			
		||||
                return String.IsNullOrEmpty(wd) ? Defaults.WorkingDirectory : wd;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -276,13 +279,13 @@ namespace winsw
 | 
			
		|||
        /// Combines the contents of all the elements of the given name,
 | 
			
		||||
        /// or return null if no element exists. Handles whitespace quotation.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private string AppendTags(string tagName)
 | 
			
		||||
        private string AppendTags(string tagName, string defaultValue = null)
 | 
			
		||||
        {
 | 
			
		||||
            XmlNode argumentNode = dom.SelectSingleNode("//" + tagName);
 | 
			
		||||
 | 
			
		||||
            if (argumentNode == null)
 | 
			
		||||
            {
 | 
			
		||||
                return null;
 | 
			
		||||
                return defaultValue;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -327,31 +330,51 @@ namespace winsw
 | 
			
		|||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    return Path.GetDirectoryName(ExecutablePath);
 | 
			
		||||
                    return Defaults.LogDirectory;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string LogMode
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                string mode = null;
 | 
			
		||||
 | 
			
		||||
                // first, backward compatibility with older configuration
 | 
			
		||||
                XmlElement e = (XmlElement)dom.SelectSingleNode("//logmode");
 | 
			
		||||
                if (e != null)
 | 
			
		||||
                {
 | 
			
		||||
                    mode = e.InnerText;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // this is more modern way, to support nested elements as configuration
 | 
			
		||||
                    e = (XmlElement)dom.SelectSingleNode("//log");
 | 
			
		||||
                    if (e != null)
 | 
			
		||||
                        mode = e.GetAttribute("mode");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (mode == null)
 | 
			
		||||
                {
 | 
			
		||||
                    mode = Defaults.LogMode;
 | 
			
		||||
                }
 | 
			
		||||
                return mode;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public LogHandler LogHandler
 | 
			
		||||
        {
 | 
			
		||||
            
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                string mode=null;
 | 
			
		||||
                
 | 
			
		||||
                // first, backward compatibility with older configuration
 | 
			
		||||
                XmlElement e = (XmlElement)dom.SelectSingleNode("//logmode");
 | 
			
		||||
                if (e!=null) {
 | 
			
		||||
                    mode = e.InnerText;
 | 
			
		||||
                } else {
 | 
			
		||||
                if (e == null)
 | 
			
		||||
                {
 | 
			
		||||
                    // this is more modern way, to support nested elements as configuration
 | 
			
		||||
                    e = (XmlElement)dom.SelectSingleNode("//log");
 | 
			
		||||
                    if (e!=null)
 | 
			
		||||
                        mode = e.GetAttribute("mode");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (mode == null) mode = "append";
 | 
			
		||||
 | 
			
		||||
                switch (mode)
 | 
			
		||||
                switch (LogMode)
 | 
			
		||||
                {
 | 
			
		||||
                    case "rotate":
 | 
			
		||||
                        return new SizeBasedRollingLogAppender(LogDirectory, BaseName);
 | 
			
		||||
| 
						 | 
				
			
			@ -384,7 +407,7 @@ namespace winsw
 | 
			
		|||
                        return new DefaultLogAppender(LogDirectory, BaseName);
 | 
			
		||||
 | 
			
		||||
                    default:
 | 
			
		||||
                        throw new InvalidDataException("Undefined logging mode: " + mode);
 | 
			
		||||
                        throw new InvalidDataException("Undefined logging mode: " + LogMode);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -397,16 +420,17 @@ namespace winsw
 | 
			
		|||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                ArrayList serviceDependencies = new ArrayList();
 | 
			
		||||
 | 
			
		||||
                var xmlNodeList = dom.SelectNodes("//depend");
 | 
			
		||||
                if (xmlNodeList != null)
 | 
			
		||||
                {
 | 
			
		||||
                    ArrayList serviceDependencies = new ArrayList();
 | 
			
		||||
                    foreach (XmlNode depend in xmlNodeList)
 | 
			
		||||
                    {
 | 
			
		||||
                        serviceDependencies.Add(depend.InnerText);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                return (string[])serviceDependencies.ToArray(typeof(string));
 | 
			
		||||
                    return (string[])serviceDependencies.ToArray(typeof(string));
 | 
			
		||||
                }
 | 
			
		||||
                return Defaults.ServiceDependencies;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -442,7 +466,7 @@ namespace winsw
 | 
			
		|||
            get
 | 
			
		||||
            {
 | 
			
		||||
                var p = SingleElement("startmode", true);
 | 
			
		||||
                if (p == null) return StartMode.Automatic;  // default value
 | 
			
		||||
                if (p == null) return Defaults.StartMode;
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    return (StartMode)Enum.Parse(typeof(StartMode), p, true);
 | 
			
		||||
| 
						 | 
				
			
			@ -460,7 +484,7 @@ namespace winsw
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// True if the service should when finished on shutdown.
 | 
			
		||||
        /// 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
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool BeepOnShutdown
 | 
			
		||||
| 
						 | 
				
			
			@ -481,7 +505,7 @@ namespace winsw
 | 
			
		|||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return SingleTimeSpanElement(dom.FirstChild, "waithint", TimeSpan.FromSeconds(15));
 | 
			
		||||
                return SingleTimeSpanElement(dom.FirstChild, "waithint", Defaults.WaitHint);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -495,7 +519,7 @@ namespace winsw
 | 
			
		|||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return SingleTimeSpanElement(dom.FirstChild, "sleeptime", TimeSpan.FromSeconds(1));
 | 
			
		||||
                return SingleTimeSpanElement(dom.FirstChild, "sleeptime", Defaults.SleepTime);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -538,13 +562,17 @@ namespace winsw
 | 
			
		|||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                List<Download> r = new List<Download>();
 | 
			
		||||
                var xmlNodeList = dom.SelectNodes("//download");
 | 
			
		||||
                if (xmlNodeList != null)
 | 
			
		||||
                    foreach (XmlNode n in xmlNodeList)
 | 
			
		||||
                    {
 | 
			
		||||
                        r.Add(new Download(n));
 | 
			
		||||
                    }
 | 
			
		||||
                if (xmlNodeList == null) 
 | 
			
		||||
                {
 | 
			
		||||
                    return Defaults.Downloads;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                List<Download> r = new List<Download>();
 | 
			
		||||
                foreach (XmlNode n in xmlNodeList)
 | 
			
		||||
                {
 | 
			
		||||
                    r.Add(new Download(n));
 | 
			
		||||
                }
 | 
			
		||||
                return r;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -587,7 +615,7 @@ namespace winsw
 | 
			
		|||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return SingleTimeSpanElement(dom.FirstChild, "resetfailure", TimeSpan.FromDays(1));
 | 
			
		||||
                return SingleTimeSpanElement(dom.FirstChild, "resetfailure", Defaults.ResetFailureAfter);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -669,13 +697,13 @@ namespace winsw
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
         /// <summary>
 | 
			
		||||
         /// Time to wait for the service to gracefully shutdown before we forcibly kill it
 | 
			
		||||
         /// Time to wait for the service to gracefully shutdown the executable before we forcibly kill it
 | 
			
		||||
         /// </summary>
 | 
			
		||||
        public TimeSpan StopTimeout
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return SingleTimeSpanElement(dom.FirstChild, "stoptimeout", TimeSpan.FromSeconds(15));
 | 
			
		||||
                return SingleTimeSpanElement(dom.FirstChild, "stoptimeout", Defaults.StopTimeout);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -689,7 +717,7 @@ namespace winsw
 | 
			
		|||
                {
 | 
			
		||||
                    return result;
 | 
			
		||||
                }
 | 
			
		||||
                return false;
 | 
			
		||||
                return Defaults.StopParentProcessFirst;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -701,7 +729,7 @@ namespace winsw
 | 
			
		|||
            get
 | 
			
		||||
            {
 | 
			
		||||
                var p = SingleElement("priority",true);
 | 
			
		||||
                if (p == null) return ProcessPriorityClass.Normal;  // default value
 | 
			
		||||
                if (p == null) return Defaults.Priority;
 | 
			
		||||
 | 
			
		||||
                return (ProcessPriorityClass)Enum.Parse(typeof(ProcessPriorityClass), p, true);
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,6 +45,7 @@
 | 
			
		|||
    <Reference Include="System.Xml" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Compile Include="Configuration\DefaultSettings.cs" />
 | 
			
		||||
    <Compile Include="Download.cs" />
 | 
			
		||||
    <Compile Include="DynamicProxy.cs" />
 | 
			
		||||
    <Compile Include="Extensions\AbstractWinSWExtension.cs" />
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +54,7 @@
 | 
			
		|||
    <Compile Include="Extensions\IWinSWExtension.cs" />
 | 
			
		||||
    <Compile Include="Extensions\WinSWExtensionDescriptor.cs" />
 | 
			
		||||
    <Compile Include="Extensions\WinSWExtensionManager.cs" />
 | 
			
		||||
    <Compile Include="Configuration\IWinSWConfiguration.cs" />
 | 
			
		||||
    <Compile Include="LogAppenders.cs" />
 | 
			
		||||
    <Compile Include="Logging\ServiceEventLogAppender.cs" />
 | 
			
		||||
    <Compile Include="Logging\IServiceEventLogProvider.cs" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue