Fix code analysis warnings

pull/685/head
NextTurn 2020-09-01 00:00:00 +08:00 committed by Next Turn
parent 42a3b87aa1
commit d08b72ceb3
6 changed files with 67 additions and 66 deletions

View File

@ -33,7 +33,7 @@ namespace WinSW.Configuration
public virtual string? ServiceAccountUserName => null; public virtual string? ServiceAccountUserName => null;
public virtual Native.SC_ACTION[] FailureActions => new Native.SC_ACTION[0]; public virtual Native.SC_ACTION[] FailureActions => Array.Empty<Native.SC_ACTION>();
public virtual TimeSpan ResetFailureAfter => TimeSpan.FromDays(1); public virtual TimeSpan ResetFailureAfter => TimeSpan.FromDays(1);
@ -55,7 +55,7 @@ namespace WinSW.Configuration
// Service management // Service management
public virtual ServiceStartMode StartMode => ServiceStartMode.Automatic; public virtual ServiceStartMode StartMode => ServiceStartMode.Automatic;
public virtual string[] ServiceDependencies => new string[0]; public virtual string[] ServiceDependencies => Array.Empty<string>();
public virtual bool Interactive => false; public virtual bool Interactive => false;

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using System.IO; using System.IO;
using System.ServiceProcess; using System.ServiceProcess;
using System.Text; using System.Text;
@ -96,6 +97,27 @@ namespace WinSW
return new XmlServiceConfig(dom); return new XmlServiceConfig(dom);
} }
private static int SingleIntElement(XmlNode parent, string tagName, int defaultValue)
{
XmlNode? e = parent.SelectSingleNode(tagName);
return e is null ? defaultValue : int.Parse(e.InnerText, NumberFormatInfo.InvariantInfo);
}
private static TimeSpan ParseTimeSpan(string v)
{
v = v.Trim();
foreach (var s in Suffix)
{
if (v.EndsWith(s.Key))
{
return TimeSpan.FromMilliseconds(int.Parse(v.Substring(0, v.Length - s.Key.Length).Trim(), NumberFormatInfo.InvariantInfo) * s.Value);
}
}
return TimeSpan.FromMilliseconds(int.Parse(v, NumberFormatInfo.InvariantInfo));
}
private string SingleElement(string tagName) private string SingleElement(string tagName)
{ {
return this.SingleElement(tagName, false)!; return this.SingleElement(tagName, false)!;
@ -119,31 +141,10 @@ namespace WinSW
return e is null ? defaultValue : bool.Parse(e.InnerText); return e is null ? defaultValue : bool.Parse(e.InnerText);
} }
private int SingleIntElement(XmlNode parent, string tagName, int defaultValue)
{
XmlNode? e = parent.SelectSingleNode(tagName);
return e is null ? defaultValue : int.Parse(e.InnerText);
}
private TimeSpan SingleTimeSpanElement(XmlNode parent, string tagName, TimeSpan defaultValue) private TimeSpan SingleTimeSpanElement(XmlNode parent, string tagName, TimeSpan defaultValue)
{ {
string? value = this.SingleElement(tagName, true); string? value = this.SingleElement(tagName, true);
return value is null ? defaultValue : this.ParseTimeSpan(value); return value is null ? defaultValue : ParseTimeSpan(value);
}
private TimeSpan ParseTimeSpan(string v)
{
v = v.Trim();
foreach (var s in Suffix)
{
if (v.EndsWith(s.Key))
{
return TimeSpan.FromMilliseconds(int.Parse(v.Substring(0, v.Length - s.Key.Length).Trim()) * s.Value);
}
}
return TimeSpan.FromMilliseconds(int.Parse(v));
} }
private static readonly Dictionary<string, long> Suffix = new Dictionary<string, long> private static readonly Dictionary<string, long> Suffix = new Dictionary<string, long>
@ -398,19 +399,19 @@ namespace WinSW
} }
var pattern = patternNode.InnerText; var pattern = patternNode.InnerText;
int period = this.SingleIntElement(e, "period", 1); int period = SingleIntElement(e, "period", 1);
return new TimeBasedRollingLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern, pattern, period); return new TimeBasedRollingLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern, pattern, period);
case "roll-by-size": case "roll-by-size":
sizeThreshold = this.SingleIntElement(e, "sizeThreshold", 10 * 1024) * SizeBasedRollingLogAppender.BytesPerKB; sizeThreshold = SingleIntElement(e, "sizeThreshold", 10 * 1024) * SizeBasedRollingLogAppender.BytesPerKB;
int keepFiles = this.SingleIntElement(e, "keepFiles", SizeBasedRollingLogAppender.DefaultFilesToKeep); int keepFiles = SingleIntElement(e, "keepFiles", SizeBasedRollingLogAppender.DefaultFilesToKeep);
return new SizeBasedRollingLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern, sizeThreshold, keepFiles); return new SizeBasedRollingLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern, sizeThreshold, keepFiles);
case "append": case "append":
return new DefaultLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern); return new DefaultLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern);
case "roll-by-size-time": case "roll-by-size-time":
sizeThreshold = this.SingleIntElement(e, "sizeThreshold", 10 * 1024) * RollingSizeTimeLogAppender.BytesPerKB; sizeThreshold = SingleIntElement(e, "sizeThreshold", 10 * 1024) * RollingSizeTimeLogAppender.BytesPerKB;
XmlNode? filePatternNode = e.SelectSingleNode("pattern"); XmlNode? filePatternNode = e.SelectSingleNode("pattern");
if (filePatternNode is null) if (filePatternNode is null)
{ {
@ -527,7 +528,7 @@ namespace WinSW
get get
{ {
string? value = this.SingleElement("preshutdownTimeout", true); string? value = this.SingleElement("preshutdownTimeout", true);
return value is null ? default : this.ParseTimeSpan(value); return value is null ? default : ParseTimeSpan(value);
} }
} }
@ -581,7 +582,7 @@ namespace WinSW
XmlNodeList? childNodes = this.dom.SelectNodes("//onfailure"); XmlNodeList? childNodes = this.dom.SelectNodes("//onfailure");
if (childNodes is null) if (childNodes is null)
{ {
return new SC_ACTION[0]; return Array.Empty<SC_ACTION>();
} }
SC_ACTION[] result = new SC_ACTION[childNodes.Count]; SC_ACTION[] result = new SC_ACTION[childNodes.Count];
@ -597,7 +598,7 @@ namespace WinSW
_ => throw new Exception("Invalid failure action: " + action) _ => throw new Exception("Invalid failure action: " + action)
}; };
XmlAttribute? delay = node.Attributes["delay"]; XmlAttribute? delay = node.Attributes["delay"];
result[i] = new SC_ACTION(type, delay != null ? this.ParseTimeSpan(delay.Value) : TimeSpan.Zero); result[i] = new SC_ACTION(type, delay != null ? ParseTimeSpan(delay.Value) : TimeSpan.Zero);
} }
return result; return result;

View File

@ -106,7 +106,7 @@ namespace WinSW
} }
// Source: http://stackoverflow.com/questions/2764577/forcing-basic-authentication-in-webrequest // Source: http://stackoverflow.com/questions/2764577/forcing-basic-authentication-in-webrequest
private void SetBasicAuthHeader(WebRequest request, string username, string password) private static void SetBasicAuthHeader(WebRequest request, string username, string password)
{ {
string authInfo = username + ":" + password; string authInfo = username + ":" + password;
authInfo = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(authInfo)); authInfo = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(authInfo));
@ -148,7 +148,7 @@ namespace WinSW
break; break;
case AuthType.Basic: case AuthType.Basic:
this.SetBasicAuthHeader(request, this.Username!, this.Password!); SetBasicAuthHeader(request, this.Username!, this.Password!);
break; break;
default: default:
@ -166,7 +166,7 @@ namespace WinSW
string tmpFilePath = this.To + ".tmp"; string tmpFilePath = this.To + ".tmp";
try try
{ {
using (WebResponse response = await request.GetResponseAsync()) using (WebResponse response = await request.GetResponseAsync().ConfigureAwait(false))
using (Stream responseStream = response.GetResponseStream()) using (Stream responseStream = response.GetResponseStream())
using (FileStream tmpStream = new FileStream(tmpFilePath, FileMode.Create)) using (FileStream tmpStream = new FileStream(tmpFilePath, FileMode.Create))
{ {
@ -175,7 +175,7 @@ namespace WinSW
lastModified = ((HttpWebResponse)response).LastModified; lastModified = ((HttpWebResponse)response).LastModified;
} }
await responseStream.CopyToAsync(tmpStream); await responseStream.CopyToAsync(tmpStream).ConfigureAwait(false);
} }
FileHelper.MoveOrReplaceFile(this.To + ".tmp", this.To); FileHelper.MoveOrReplaceFile(this.To + ".tmp", this.To);

View File

@ -19,6 +19,33 @@ namespace WinSW.Extensions
this.Extensions = new Dictionary<string, IWinSWExtension>(); this.Extensions = new Dictionary<string, IWinSWExtension>();
} }
private static IWinSWExtension CreateExtensionInstance(string id, string className)
{
object created;
try
{
Type? t = Type.GetType(className);
if (t is null)
{
throw new ExtensionException(id, "Class " + className + " does not exist");
}
created = Activator.CreateInstance(t)!;
}
catch (Exception ex)
{
throw new ExtensionException(id, "Cannot load the class by name: " + className, ex);
}
if (!(created is IWinSWExtension extension))
{
throw new ExtensionException(id, "The loaded class is not a WinSW extension: " + className + ". Type is " + created.GetType());
}
return extension;
}
/// <summary> /// <summary>
/// Notifies all extensions that the wrapper is being started. /// Notifies all extensions that the wrapper is being started.
/// They are supposed to run the initialization logic. /// They are supposed to run the initialization logic.
@ -137,7 +164,7 @@ namespace WinSW.Extensions
var descriptor = WinSWExtensionDescriptor.FromXml(configNode); var descriptor = WinSWExtensionDescriptor.FromXml(configNode);
if (descriptor.Enabled) if (descriptor.Enabled)
{ {
IWinSWExtension extension = this.CreateExtensionInstance(descriptor.Id, descriptor.ClassName); IWinSWExtension extension = CreateExtensionInstance(descriptor.Id, descriptor.ClassName);
extension.Descriptor = descriptor; extension.Descriptor = descriptor;
try try
{ {
@ -146,7 +173,7 @@ namespace WinSW.Extensions
catch (Exception ex) catch (Exception ex)
{ // Consider any unexpected exception as fatal { // Consider any unexpected exception as fatal
Log.Fatal("Failed to configure the extension " + id, ex); Log.Fatal("Failed to configure the extension " + id, ex);
throw ex; throw;
} }
this.Extensions.Add(id, extension); this.Extensions.Add(id, extension);
@ -158,33 +185,6 @@ namespace WinSW.Extensions
} }
} }
private IWinSWExtension CreateExtensionInstance(string id, string className)
{
object created;
try
{
Type? t = Type.GetType(className);
if (t is null)
{
throw new ExtensionException(id, "Class " + className + " does not exist");
}
created = Activator.CreateInstance(t)!;
}
catch (Exception ex)
{
throw new ExtensionException(id, "Cannot load the class by name: " + className, ex);
}
if (!(created is IWinSWExtension extension))
{
throw new ExtensionException(id, "The loaded class is not a WinSW extension: " + className + ". Type is " + created.GetType());
}
return extension;
}
#endregion #endregion
} }
} }

View File

@ -5,7 +5,7 @@ using System.Xml;
namespace WinSW.Util namespace WinSW.Util
{ {
public class XmlHelper public static class XmlHelper
{ {
/// <summary> /// <summary>
/// Retrieves a single string element /// Retrieves a single string element

View File

@ -4,7 +4,7 @@
/// Class, which contains generic information about WinSW runtime. /// Class, which contains generic information about WinSW runtime.
/// This information can be used by the service and extensions. /// This information can be used by the service and extensions.
/// </summary> /// </summary>
public class WinSWSystem public static class WinSWSystem
{ {
/// <summary> /// <summary>
/// Prefix for all environment variables being injected for WinSW /// Prefix for all environment variables being injected for WinSW