mirror of https://github.com/winsw/winsw
Ensure basic console logging
parent
12525cc8fc
commit
2ab79083d4
|
@ -102,7 +102,7 @@ namespace WinSW
|
|||
|
||||
private static int SingleIntElement(XmlNode parent, string tagName, int defaultValue)
|
||||
{
|
||||
XmlNode? e = parent.SelectSingleNode(tagName);
|
||||
var e = parent.SelectSingleNode(tagName);
|
||||
|
||||
return e is null ? defaultValue : int.Parse(e.InnerText, NumberFormatInfo.InvariantInfo);
|
||||
}
|
||||
|
@ -128,13 +128,13 @@ namespace WinSW
|
|||
|
||||
private string? SingleElementOrNull(string tagName)
|
||||
{
|
||||
XmlNode? n = this.root.SelectSingleNode(tagName);
|
||||
var n = this.root.SelectSingleNode(tagName);
|
||||
return n is null ? null : Environment.ExpandEnvironmentVariables(n.InnerText);
|
||||
}
|
||||
|
||||
private bool SingleBoolElementOrDefault(string tagName, bool defaultValue)
|
||||
{
|
||||
XmlNode? e = this.root.SelectSingleNode(tagName);
|
||||
var e = this.root.SelectSingleNode(tagName);
|
||||
|
||||
return e is null ? defaultValue : bool.Parse(e.InnerText);
|
||||
}
|
||||
|
@ -208,14 +208,14 @@ namespace WinSW
|
|||
{
|
||||
get
|
||||
{
|
||||
XmlNode? argumentNode = this.ExtensionsConfiguration;
|
||||
XmlNodeList? extensions = argumentNode?.SelectNodes("extension");
|
||||
var argumentNode = this.ExtensionsConfiguration;
|
||||
var extensions = argumentNode?.SelectNodes("extension");
|
||||
if (extensions is null)
|
||||
{
|
||||
return new List<string>(0);
|
||||
}
|
||||
|
||||
List<string> result = new List<string>(extensions.Count);
|
||||
var result = new List<string>(extensions.Count);
|
||||
for (int i = 0; i < extensions.Count; i++)
|
||||
{
|
||||
result.Add(XmlHelper.SingleAttribute<string>((XmlElement)extensions[i]!, "id"));
|
||||
|
@ -239,7 +239,7 @@ namespace WinSW
|
|||
string? mode = null;
|
||||
|
||||
// first, backward compatibility with older configuration
|
||||
XmlElement? e = (XmlElement?)this.root.SelectSingleNode("logmode");
|
||||
var e = (XmlElement?)this.root.SelectSingleNode("logmode");
|
||||
if (e != null)
|
||||
{
|
||||
mode = e.InnerText;
|
||||
|
@ -272,7 +272,7 @@ namespace WinSW
|
|||
{
|
||||
get
|
||||
{
|
||||
XmlElement? e = (XmlElement?)this.root.SelectSingleNode("logmode");
|
||||
var e = (XmlElement?)this.root.SelectSingleNode("logmode");
|
||||
|
||||
// this is more modern way, to support nested elements as configuration
|
||||
e ??= (XmlElement?)this.root.SelectSingleNode("log")!; // WARNING: NRE
|
||||
|
@ -293,13 +293,13 @@ namespace WinSW
|
|||
return new RollingLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern);
|
||||
|
||||
case "roll-by-time":
|
||||
XmlNode? patternNode = e.SelectSingleNode("pattern");
|
||||
var patternNode = e.SelectSingleNode("pattern");
|
||||
if (patternNode is null)
|
||||
{
|
||||
throw new InvalidDataException("Time Based rolling policy is specified but no pattern can be found in configuration XML.");
|
||||
}
|
||||
|
||||
var pattern = patternNode.InnerText;
|
||||
string? pattern = patternNode.InnerText;
|
||||
int period = SingleIntElement(e, "period", 1);
|
||||
return new TimeBasedRollingLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern, pattern, period);
|
||||
|
||||
|
@ -313,18 +313,18 @@ namespace WinSW
|
|||
|
||||
case "roll-by-size-time":
|
||||
sizeThreshold = SingleIntElement(e, "sizeThreshold", 10 * 1024) * RollingSizeTimeLogAppender.BytesPerKB;
|
||||
XmlNode? filePatternNode = e.SelectSingleNode("pattern");
|
||||
var filePatternNode = e.SelectSingleNode("pattern");
|
||||
if (filePatternNode is null)
|
||||
{
|
||||
throw new InvalidDataException("Roll-Size-Time Based rolling policy is specified but no pattern can be found in configuration XML.");
|
||||
}
|
||||
|
||||
XmlNode? autoRollAtTimeNode = e.SelectSingleNode("autoRollAtTime");
|
||||
var autoRollAtTimeNode = e.SelectSingleNode("autoRollAtTime");
|
||||
TimeSpan? autoRollAtTime = null;
|
||||
if (autoRollAtTimeNode != null)
|
||||
{
|
||||
// validate it
|
||||
if (!TimeSpan.TryParse(autoRollAtTimeNode.InnerText, out TimeSpan autoRollAtTimeValue))
|
||||
if (!TimeSpan.TryParse(autoRollAtTimeNode.InnerText, out var 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.");
|
||||
}
|
||||
|
@ -332,7 +332,7 @@ namespace WinSW
|
|||
autoRollAtTime = autoRollAtTimeValue;
|
||||
}
|
||||
|
||||
XmlNode? zipolderthannumdaysNode = e.SelectSingleNode("zipOlderThanNumDays");
|
||||
var zipolderthannumdaysNode = e.SelectSingleNode("zipOlderThanNumDays");
|
||||
int? zipolderthannumdays = null;
|
||||
if (zipolderthannumdaysNode != null)
|
||||
{
|
||||
|
@ -345,7 +345,7 @@ namespace WinSW
|
|||
zipolderthannumdays = zipolderthannumdaysValue;
|
||||
}
|
||||
|
||||
XmlNode? zipdateformatNode = e.SelectSingleNode("zipDateFormat");
|
||||
var zipdateformatNode = e.SelectSingleNode("zipDateFormat");
|
||||
string zipdateformat = zipdateformatNode is null ? "yyyyMM" : zipdateformatNode.InnerText;
|
||||
|
||||
return new RollingSizeTimeLogAppender(this.LogDirectory, this.LogName, this.OutFileDisabled, this.ErrFileDisabled, this.OutFilePattern, this.ErrFilePattern, sizeThreshold, filePatternNode.InnerText, autoRollAtTime, zipolderthannumdays, zipdateformat);
|
||||
|
@ -363,7 +363,7 @@ namespace WinSW
|
|||
{
|
||||
get
|
||||
{
|
||||
XmlNodeList? nodeList = this.root.SelectNodes("depend");
|
||||
var nodeList = this.root.SelectNodes("depend");
|
||||
if (nodeList is null)
|
||||
{
|
||||
return base.ServiceDependencies;
|
||||
|
@ -404,7 +404,7 @@ namespace WinSW
|
|||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
var builder = new StringBuilder();
|
||||
builder.AppendLine("Start mode in XML must be one of the following:");
|
||||
foreach (string sm in Enum.GetNames(typeof(ServiceStartMode)))
|
||||
{
|
||||
|
@ -457,13 +457,13 @@ namespace WinSW
|
|||
{
|
||||
get
|
||||
{
|
||||
XmlNodeList? nodeList = this.root.SelectNodes("download");
|
||||
var nodeList = this.root.SelectNodes("download");
|
||||
if (nodeList is null)
|
||||
{
|
||||
return base.Downloads;
|
||||
}
|
||||
|
||||
List<Download> result = new List<Download>(nodeList.Count);
|
||||
var result = new List<Download>(nodeList.Count);
|
||||
for (int i = 0; i < nodeList.Count; i++)
|
||||
{
|
||||
if (nodeList[i] is XmlElement element)
|
||||
|
@ -480,25 +480,25 @@ namespace WinSW
|
|||
{
|
||||
get
|
||||
{
|
||||
XmlNodeList? childNodes = this.root.SelectNodes("onfailure");
|
||||
var childNodes = this.root.SelectNodes("onfailure");
|
||||
if (childNodes is null)
|
||||
{
|
||||
return Array.Empty<SC_ACTION>();
|
||||
}
|
||||
|
||||
SC_ACTION[] result = new SC_ACTION[childNodes.Count];
|
||||
var result = new SC_ACTION[childNodes.Count];
|
||||
for (int i = 0; i < childNodes.Count; i++)
|
||||
{
|
||||
XmlNode node = childNodes[i]!;
|
||||
var node = childNodes[i]!;
|
||||
string action = node.Attributes!["action"]?.Value ?? throw new InvalidDataException("'action' is missing");
|
||||
SC_ACTION_TYPE type = action switch
|
||||
var type = action switch
|
||||
{
|
||||
"restart" => SC_ACTION_TYPE.SC_ACTION_RESTART,
|
||||
"none" => SC_ACTION_TYPE.SC_ACTION_NONE,
|
||||
"reboot" => SC_ACTION_TYPE.SC_ACTION_REBOOT,
|
||||
_ => throw new Exception("Invalid failure action: " + action)
|
||||
};
|
||||
XmlAttribute? delay = node.Attributes["delay"];
|
||||
var delay = node.Attributes["delay"];
|
||||
result[i] = new SC_ACTION(type, delay != null ? ParseTimeSpan(delay.Value) : TimeSpan.Zero);
|
||||
}
|
||||
|
||||
|
@ -510,11 +510,11 @@ namespace WinSW
|
|||
|
||||
protected string? GetServiceAccountPart(string subNodeName)
|
||||
{
|
||||
XmlNode? node = this.root.SelectSingleNode("serviceaccount");
|
||||
var node = this.root.SelectSingleNode("serviceaccount");
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
XmlNode? subNode = node.SelectSingleNode(subNodeName);
|
||||
var subNode = node.SelectSingleNode(subNodeName);
|
||||
if (subNode != null)
|
||||
{
|
||||
return subNode.InnerText;
|
||||
|
@ -583,11 +583,11 @@ namespace WinSW
|
|||
|
||||
private Dictionary<string, string> LoadEnvironmentVariables()
|
||||
{
|
||||
XmlNodeList nodeList = this.root.SelectNodes("env")!;
|
||||
Dictionary<string, string> environment = new Dictionary<string, string>(nodeList.Count);
|
||||
var nodeList = this.root.SelectNodes("env")!;
|
||||
var environment = new Dictionary<string, string>(nodeList.Count);
|
||||
for (int i = 0; i < nodeList.Count; i++)
|
||||
{
|
||||
XmlNode node = nodeList[i]!;
|
||||
var node = nodeList[i]!;
|
||||
string key = node.Attributes!["name"]?.Value ?? throw new InvalidDataException("'name' is missing");
|
||||
string value = Environment.ExpandEnvironmentVariables(node.Attributes["value"]?.Value ?? throw new InvalidDataException("'value' is missing"));
|
||||
environment[key] = value;
|
||||
|
@ -600,7 +600,7 @@ namespace WinSW
|
|||
|
||||
private ProcessCommand GetProcessCommand(string name)
|
||||
{
|
||||
XmlNode? node = this.root.SelectSingleNode(name);
|
||||
var node = this.root.SelectSingleNode(name);
|
||||
return node is null ? default : new ProcessCommand
|
||||
{
|
||||
Executable = GetInnerText(Names.Executable),
|
||||
|
|
|
@ -121,10 +121,10 @@ namespace WinSW
|
|||
/// </exception>
|
||||
public async Task PerformAsync()
|
||||
{
|
||||
WebRequest request = WebRequest.Create(this.From);
|
||||
var request = WebRequest.Create(this.From);
|
||||
if (!string.IsNullOrEmpty(this.Proxy))
|
||||
{
|
||||
CustomProxyInformation proxyInformation = new CustomProxyInformation(this.Proxy!);
|
||||
var proxyInformation = new CustomProxyInformation(this.Proxy!);
|
||||
if (proxyInformation.Credentials != null)
|
||||
{
|
||||
request.Proxy = new WebProxy(proxyInformation.ServerAddress, false, null, proxyInformation.Credentials);
|
||||
|
@ -166,9 +166,9 @@ namespace WinSW
|
|||
string tmpFilePath = this.To + ".tmp";
|
||||
try
|
||||
{
|
||||
using (WebResponse response = await request.GetResponseAsync().ConfigureAwait(false))
|
||||
using (Stream responseStream = response.GetResponseStream())
|
||||
using (FileStream tmpStream = new FileStream(tmpFilePath, FileMode.Create))
|
||||
using (var response = await request.GetResponseAsync().ConfigureAwait(false))
|
||||
using (var responseStream = response.GetResponseStream())
|
||||
using (var tmpStream = new FileStream(tmpFilePath, FileMode.Create))
|
||||
{
|
||||
if (supportsIfModifiedSince)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace WinSW.Extensions
|
|||
|
||||
try
|
||||
{
|
||||
Type? t = Type.GetType(className);
|
||||
var t = Type.GetType(className);
|
||||
if (t is null)
|
||||
{
|
||||
throw new ExtensionException(id, "Class " + className + " does not exist");
|
||||
|
@ -154,8 +154,8 @@ namespace WinSW.Extensions
|
|||
throw new ExtensionException(id, "Extension has been already loaded");
|
||||
}
|
||||
|
||||
XmlNode? extensionsConfig = this.ServiceConfig.ExtensionsConfiguration;
|
||||
XmlElement? configNode = extensionsConfig is null ? null : extensionsConfig.SelectSingleNode("extension[@id='" + id + "'][1]") as XmlElement;
|
||||
var extensionsConfig = this.ServiceConfig.ExtensionsConfiguration;
|
||||
var configNode = extensionsConfig is null ? null : extensionsConfig.SelectSingleNode("extension[@id='" + id + "'][1]") as XmlElement;
|
||||
if (configNode is null)
|
||||
{
|
||||
throw new ExtensionException(id, "Cannot get the configuration entry");
|
||||
|
@ -164,7 +164,7 @@ namespace WinSW.Extensions
|
|||
var descriptor = WinSWExtensionDescriptor.FromXml(configNode);
|
||||
if (descriptor.Enabled)
|
||||
{
|
||||
IWinSWExtension extension = CreateExtensionInstance(descriptor.Id, descriptor.ClassName);
|
||||
var extension = CreateExtensionInstance(descriptor.Id, descriptor.ClassName);
|
||||
extension.Descriptor = descriptor;
|
||||
try
|
||||
{
|
||||
|
|
|
@ -243,10 +243,10 @@ namespace WinSW
|
|||
/// </summary>
|
||||
private async Task CopyStreamWithDateRotationAsync(StreamReader reader, string ext)
|
||||
{
|
||||
PeriodicRollingCalendar periodicRollingCalendar = new PeriodicRollingCalendar(this.Pattern, this.Period);
|
||||
var periodicRollingCalendar = new PeriodicRollingCalendar(this.Pattern, this.Period);
|
||||
periodicRollingCalendar.Init();
|
||||
|
||||
StreamWriter writer = this.CreateWriter(new FileStream(this.BaseLogFileName + "_" + periodicRollingCalendar.Format + ext, FileMode.Append));
|
||||
var writer = this.CreateWriter(new FileStream(this.BaseLogFileName + "_" + periodicRollingCalendar.Format + ext, FileMode.Append));
|
||||
string? line;
|
||||
while ((line = await reader.ReadLineAsync()) != null)
|
||||
{
|
||||
|
@ -302,7 +302,7 @@ namespace WinSW
|
|||
/// </summary>
|
||||
private async Task CopyStreamWithRotationAsync(StreamReader reader, string ext)
|
||||
{
|
||||
StreamWriter writer = this.CreateWriter(new FileStream(this.BaseLogFileName + ext, FileMode.Append));
|
||||
var writer = this.CreateWriter(new FileStream(this.BaseLogFileName + ext, FileMode.Append));
|
||||
long fileLength = new FileInfo(this.BaseLogFileName + ext).Length;
|
||||
|
||||
string? line;
|
||||
|
@ -426,20 +426,20 @@ 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
|
||||
var fileLock = new object();
|
||||
object? fileLock = new object();
|
||||
|
||||
var baseDirectory = Path.GetDirectoryName(this.BaseLogFileName)!;
|
||||
var baseFileName = Path.GetFileName(this.BaseLogFileName);
|
||||
var logFile = this.BaseLogFileName + extension;
|
||||
string? baseDirectory = Path.GetDirectoryName(this.BaseLogFileName)!;
|
||||
string? baseFileName = Path.GetFileName(this.BaseLogFileName);
|
||||
string? logFile = this.BaseLogFileName + extension;
|
||||
|
||||
var writer = this.CreateWriter(new FileStream(logFile, FileMode.Append));
|
||||
var fileLength = new FileInfo(logFile).Length;
|
||||
long 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 (this.AutoRollAtTime is TimeSpan autoRollAtTime)
|
||||
{
|
||||
// Run at start
|
||||
var tickTime = this.SetupRollTimer(autoRollAtTime);
|
||||
double tickTime = this.SetupRollTimer(autoRollAtTime);
|
||||
var timer = new System.Timers.Timer(tickTime);
|
||||
timer.Elapsed += (_, _) =>
|
||||
{
|
||||
|
@ -451,8 +451,8 @@ namespace WinSW
|
|||
writer.Dispose();
|
||||
|
||||
var now = DateTime.Now.AddDays(-1);
|
||||
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));
|
||||
int nextFileNumber = this.GetNextFileNumber(extension, baseDirectory, baseFileName, now);
|
||||
string? nextFileName = Path.Combine(baseDirectory, string.Format("{0}.{1}.#{2:D4}{3}", baseFileName, now.ToString(this.FilePattern), nextFileNumber, extension));
|
||||
File.Move(logFile, nextFileName);
|
||||
|
||||
writer = this.CreateWriter(new FileStream(logFile, FileMode.Create));
|
||||
|
@ -488,8 +488,8 @@ namespace WinSW
|
|||
{
|
||||
// roll file
|
||||
var now = DateTime.Now;
|
||||
var nextFileNumber = this.GetNextFileNumber(extension, baseDirectory, baseFileName, now);
|
||||
var nextFileName = Path.Combine(
|
||||
int nextFileNumber = this.GetNextFileNumber(extension, baseDirectory, baseFileName, now);
|
||||
string? nextFileName = Path.Combine(
|
||||
baseDirectory,
|
||||
string.Format("{0}.{1}.#{2:D4}{3}", baseFileName, now.ToString(this.FilePattern), nextFileNumber, extension));
|
||||
File.Move(logFile, nextFileName);
|
||||
|
@ -589,21 +589,21 @@ 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(this.FilePattern), ext));
|
||||
int nextFileNumber = 0;
|
||||
string[]? files = Directory.GetFiles(baseDirectory, string.Format("{0}.{1}.#*{2}", baseFileName, now.ToString(this.FilePattern), ext));
|
||||
if (files.Length == 0)
|
||||
{
|
||||
nextFileNumber = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var f in files)
|
||||
foreach (string? f in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
var filenameOnly = Path.GetFileNameWithoutExtension(f);
|
||||
var hashIndex = filenameOnly.IndexOf('#');
|
||||
var lastNumberAsString = filenameOnly.Substring(hashIndex + 1, 4);
|
||||
string? filenameOnly = Path.GetFileNameWithoutExtension(f);
|
||||
int hashIndex = filenameOnly.IndexOf('#');
|
||||
string? lastNumberAsString = filenameOnly.Substring(hashIndex + 1, 4);
|
||||
if (int.TryParse(lastNumberAsString, out int lastNumber))
|
||||
{
|
||||
if (lastNumber > nextFileNumber)
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace WinSW.Native
|
|||
IntPtr.Zero,
|
||||
ref inBufferSize);
|
||||
|
||||
IntPtr inBuffer = Marshal.AllocCoTaskMem(inBufferSize);
|
||||
var inBuffer = Marshal.AllocCoTaskMem(inBufferSize);
|
||||
try
|
||||
{
|
||||
if (!CredPackAuthenticationBuffer(
|
||||
|
@ -33,7 +33,7 @@ namespace WinSW.Native
|
|||
Throw.Command.Win32Exception("Failed to pack auth buffer.");
|
||||
}
|
||||
|
||||
CREDUI_INFO info = new CREDUI_INFO
|
||||
var info = new CREDUI_INFO
|
||||
{
|
||||
Size = Marshal.SizeOf(typeof(CREDUI_INFO)),
|
||||
CaptionText = caption,
|
||||
|
@ -47,7 +47,7 @@ namespace WinSW.Native
|
|||
ref authPackage,
|
||||
inBuffer,
|
||||
inBufferSize,
|
||||
out IntPtr outBuffer,
|
||||
out var outBuffer,
|
||||
out uint outBufferSize,
|
||||
ref save,
|
||||
CREDUIWIN_GENERIC);
|
||||
|
|
|
@ -11,24 +11,24 @@ namespace WinSW.Native
|
|||
/// <exception cref="CommandException" />
|
||||
internal static unsafe bool UpdateCompanyName(string path, string outputPath, string companyName)
|
||||
{
|
||||
IntPtr module = LoadLibraryW(path);
|
||||
var module = LoadLibraryW(path);
|
||||
try
|
||||
{
|
||||
IntPtr verInfo = FindResourceW(module, VS_VERSION_INFO, RT_VERSION);
|
||||
var verInfo = FindResourceW(module, VS_VERSION_INFO, RT_VERSION);
|
||||
if (verInfo == IntPtr.Zero)
|
||||
{
|
||||
Exit();
|
||||
}
|
||||
|
||||
IntPtr resData = LoadResource(module, verInfo);
|
||||
var resData = LoadResource(module, verInfo);
|
||||
if (resData == IntPtr.Zero)
|
||||
{
|
||||
Exit();
|
||||
}
|
||||
|
||||
IntPtr resAddr = LockResource(resData);
|
||||
var resAddr = LockResource(resData);
|
||||
|
||||
IntPtr address = resAddr;
|
||||
var address = resAddr;
|
||||
int offset = 0;
|
||||
|
||||
short length = ((short*)address)[0];
|
||||
|
@ -81,7 +81,7 @@ namespace WinSW.Native
|
|||
int newLength = companyName.Length + 1;
|
||||
Debug.Assert(newLength > 12 && newLength <= 16);
|
||||
|
||||
IntPtr newAddress = Marshal.AllocHGlobal(length);
|
||||
var newAddress = Marshal.AllocHGlobal(length);
|
||||
try
|
||||
{
|
||||
Buffer.MemoryCopy((void*)resAddr, (void*)newAddress, length, length);
|
||||
|
@ -94,7 +94,7 @@ namespace WinSW.Native
|
|||
|
||||
File.Copy(path, outputPath, true);
|
||||
|
||||
IntPtr update = BeginUpdateResourceW(outputPath, false);
|
||||
var update = BeginUpdateResourceW(outputPath, false);
|
||||
if (update == IntPtr.Zero)
|
||||
{
|
||||
Exit();
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace WinSW.Native
|
|||
/// <exception cref="Win32Exception" />
|
||||
internal static void AddServiceLogonRight(ref string userName)
|
||||
{
|
||||
IntPtr sid = GetAccountSid(ref userName);
|
||||
var sid = GetAccountSid(ref userName);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ namespace WinSW.Native
|
|||
|
||||
_ = LookupAccountName(null, accountName, IntPtr.Zero, ref sidSize, null, ref domainNameLength, out _);
|
||||
|
||||
IntPtr sid = Marshal.AllocHGlobal(sidSize);
|
||||
var sid = Marshal.AllocHGlobal(sidSize);
|
||||
try
|
||||
{
|
||||
string? domainName = domainNameLength == 0 ? null : new string('\0', domainNameLength - 1);
|
||||
|
@ -64,7 +64,7 @@ namespace WinSW.Native
|
|||
/// <exception cref="Win32Exception" />
|
||||
private static void AddAccountRight(IntPtr sid, string rightName)
|
||||
{
|
||||
uint status = LsaOpenPolicy(IntPtr.Zero, default, PolicyAccess.ALL_ACCESS, out IntPtr policyHandle);
|
||||
uint status = LsaOpenPolicy(IntPtr.Zero, default, PolicyAccess.ALL_ACCESS, out var policyHandle);
|
||||
if (status != 0)
|
||||
{
|
||||
throw new Win32Exception(LsaNtStatusToWinError(status));
|
||||
|
@ -72,7 +72,7 @@ namespace WinSW.Native
|
|||
|
||||
try
|
||||
{
|
||||
LSA_UNICODE_STRING userRight = new LSA_UNICODE_STRING
|
||||
var userRight = new LSA_UNICODE_STRING
|
||||
{
|
||||
Buffer = rightName,
|
||||
Length = (ushort)(rightName.Length * sizeof(char)),
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace WinSW.Native
|
|||
/// <exception cref="CommandException" />
|
||||
internal static ServiceManager Open(ServiceManagerAccess access = ServiceManagerAccess.All)
|
||||
{
|
||||
IntPtr handle = OpenSCManager(null, null, access);
|
||||
var handle = OpenSCManager(null, null, access);
|
||||
if (handle == IntPtr.Zero)
|
||||
{
|
||||
Throw.Command.Win32Exception("Failed to open the service control manager database.");
|
||||
|
@ -77,7 +77,7 @@ namespace WinSW.Native
|
|||
string? username,
|
||||
string? password)
|
||||
{
|
||||
IntPtr handle = ServiceApis.CreateService(
|
||||
var handle = ServiceApis.CreateService(
|
||||
this.handle,
|
||||
serviceName,
|
||||
displayName,
|
||||
|
@ -113,7 +113,7 @@ namespace WinSW.Native
|
|||
out _,
|
||||
ref resume);
|
||||
|
||||
IntPtr services = Marshal.AllocHGlobal(bytesNeeded);
|
||||
var services = Marshal.AllocHGlobal(bytesNeeded);
|
||||
try
|
||||
{
|
||||
if (!EnumServicesStatus(
|
||||
|
@ -141,7 +141,7 @@ namespace WinSW.Native
|
|||
/// <exception cref="CommandException" />
|
||||
internal unsafe Service OpenService(char* serviceName, ServiceAccess access = ServiceAccess.All)
|
||||
{
|
||||
IntPtr serviceHandle = ServiceApis.OpenService(this.handle, serviceName, access);
|
||||
var serviceHandle = ServiceApis.OpenService(this.handle, serviceName, access);
|
||||
if (serviceHandle == IntPtr.Zero)
|
||||
{
|
||||
Throw.Command.Win32Exception("Failed to open the service.");
|
||||
|
@ -153,7 +153,7 @@ namespace WinSW.Native
|
|||
/// <exception cref="CommandException" />
|
||||
internal Service OpenService(string serviceName, ServiceAccess access = ServiceAccess.All)
|
||||
{
|
||||
IntPtr serviceHandle = ServiceApis.OpenService(this.handle, serviceName, access);
|
||||
var serviceHandle = ServiceApis.OpenService(this.handle, serviceName, access);
|
||||
if (serviceHandle == IntPtr.Zero)
|
||||
{
|
||||
Throw.Command.Win32Exception("Failed to open the service.");
|
||||
|
@ -164,7 +164,7 @@ namespace WinSW.Native
|
|||
|
||||
internal bool ServiceExists(string serviceName)
|
||||
{
|
||||
IntPtr serviceHandle = ServiceApis.OpenService(this.handle, serviceName, ServiceAccess.All);
|
||||
var serviceHandle = ServiceApis.OpenService(this.handle, serviceName, ServiceAccess.All);
|
||||
if (serviceHandle == IntPtr.Zero)
|
||||
{
|
||||
return false;
|
||||
|
@ -202,7 +202,7 @@ namespace WinSW.Native
|
|||
0,
|
||||
out int bytesNeeded);
|
||||
|
||||
IntPtr config = Marshal.AllocHGlobal(bytesNeeded);
|
||||
var config = Marshal.AllocHGlobal(bytesNeeded);
|
||||
try
|
||||
{
|
||||
if (!QueryServiceConfig(
|
||||
|
@ -231,7 +231,7 @@ namespace WinSW.Native
|
|||
if (!QueryServiceStatusEx(
|
||||
this.handle,
|
||||
ServiceStatusType.ProcessInfo,
|
||||
out SERVICE_STATUS_PROCESS status,
|
||||
out var status,
|
||||
sizeof(SERVICE_STATUS_PROCESS),
|
||||
out _))
|
||||
{
|
||||
|
@ -247,7 +247,7 @@ namespace WinSW.Native
|
|||
{
|
||||
get
|
||||
{
|
||||
if (!QueryServiceStatus(this.handle, out SERVICE_STATUS status))
|
||||
if (!QueryServiceStatus(this.handle, out var status))
|
||||
{
|
||||
Throw.Command.Win32Exception("Failed to query service status.");
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ namespace WinSW.Native
|
|||
/// <exception cref="CommandException" />
|
||||
internal void SetStatus(IntPtr statusHandle, ServiceControllerStatus state)
|
||||
{
|
||||
if (!QueryServiceStatus(this.handle, out SERVICE_STATUS status))
|
||||
if (!QueryServiceStatus(this.handle, out var status))
|
||||
{
|
||||
Throw.Command.Win32Exception("Failed to query service status.");
|
||||
}
|
||||
|
|
|
@ -199,7 +199,7 @@ namespace WinSW.Native
|
|||
var serviceName = new ReadOnlySpan<char>(this.ServiceName, new ReadOnlySpan<char>(this.ServiceName, 256).IndexOf('\0'));
|
||||
var displayName = new ReadOnlySpan<char>(this.DisplayName, new ReadOnlySpan<char>(this.DisplayName, 256).IndexOf('\0'));
|
||||
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
return string.Concat(displayName, " (", serviceName, ")");
|
||||
#else
|
||||
return string.Concat(displayName.ToString(), " (", serviceName.ToString(), ")");
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace WinSW.Native
|
|||
internal static void Win32Exception(int error, string message)
|
||||
{
|
||||
Debug.Assert(error != 0);
|
||||
Win32Exception inner = new Win32Exception(error);
|
||||
var inner = new Win32Exception(error);
|
||||
Debug.Assert(message.EndsWith("."));
|
||||
throw new CommandException(message + ' ' + inner.Message, inner);
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ namespace WinSW.Native
|
|||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Win32Exception()
|
||||
{
|
||||
Win32Exception inner = new Win32Exception();
|
||||
var inner = new Win32Exception();
|
||||
Debug.Assert(inner.NativeErrorCode != 0);
|
||||
throw new CommandException(inner);
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ namespace WinSW.Native
|
|||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Win32Exception(string message)
|
||||
{
|
||||
Win32Exception inner = new Win32Exception();
|
||||
var inner = new Win32Exception();
|
||||
Debug.Assert(inner.NativeErrorCode != 0);
|
||||
Debug.Assert(message.EndsWith("."));
|
||||
throw new CommandException(message + ' ' + inner.Message, inner);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
#if !NETCOREAPP
|
||||
#if !NET
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
/// <summary>Specifies that null is allowed as an input even if the corresponding type disallows it.</summary>
|
||||
|
|
|
@ -40,15 +40,15 @@ namespace WinSW
|
|||
|
||||
private PeriodicityType DeterminePeriodicityType()
|
||||
{
|
||||
PeriodicRollingCalendar periodicRollingCalendar = new PeriodicRollingCalendar(this.format, this.period);
|
||||
DateTime epoch = new DateTime(1970, 1, 1);
|
||||
var periodicRollingCalendar = new PeriodicRollingCalendar(this.format, this.period);
|
||||
var epoch = new DateTime(1970, 1, 1);
|
||||
|
||||
foreach (PeriodicityType i in ValidOrderedList)
|
||||
foreach (var i in ValidOrderedList)
|
||||
{
|
||||
string r0 = epoch.ToString(this.format);
|
||||
periodicRollingCalendar.Periodicity = i;
|
||||
|
||||
DateTime next = periodicRollingCalendar.NextTriggeringTime(epoch, 1);
|
||||
var next = periodicRollingCalendar.NextTriggeringTime(epoch, 1);
|
||||
string r1 = next.ToString(this.format);
|
||||
|
||||
if (r0 != r1)
|
||||
|
@ -91,7 +91,7 @@ namespace WinSW
|
|||
{
|
||||
get
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
var now = DateTime.Now;
|
||||
if (now > this.nextRoll)
|
||||
{
|
||||
this.currentRoll = now;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#if !NETCOREAPP
|
||||
#if !NET
|
||||
using System;
|
||||
#endif
|
||||
using System.IO;
|
||||
#if !NETCOREAPP
|
||||
#if !NET
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
|
||||
|
@ -12,7 +12,7 @@ namespace WinSW.Util
|
|||
{
|
||||
public static void MoveOrReplaceFile(string sourceFileName, string destFileName)
|
||||
{
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
File.Move(sourceFileName, destFileName, true);
|
||||
#else
|
||||
string sourceFilePath = Path.GetFullPath(sourceFileName);
|
||||
|
@ -24,7 +24,7 @@ namespace WinSW.Util
|
|||
}
|
||||
#endif
|
||||
}
|
||||
#if !NETCOREAPP
|
||||
#if !NET
|
||||
|
||||
private static Exception GetExceptionForLastWin32Error(string path) => Marshal.GetLastWin32Error() switch
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace WinSW.Util
|
|||
{
|
||||
StopPrivate(process, millisecondsTimeout);
|
||||
|
||||
foreach (Process child in GetChildren(process))
|
||||
foreach (var child in GetChildren(process))
|
||||
{
|
||||
using (child)
|
||||
{
|
||||
|
@ -29,7 +29,7 @@ namespace WinSW.Util
|
|||
|
||||
internal static void StopDescendants(this Process process, int millisecondsTimeout)
|
||||
{
|
||||
foreach (Process child in GetChildren(process))
|
||||
foreach (var child in GetChildren(process))
|
||||
{
|
||||
using (child)
|
||||
{
|
||||
|
@ -40,12 +40,12 @@ namespace WinSW.Util
|
|||
|
||||
internal static unsafe List<Process> GetChildren(this Process process)
|
||||
{
|
||||
DateTime startTime = process.StartTime;
|
||||
var startTime = process.StartTime;
|
||||
int processId = process.Id;
|
||||
|
||||
var children = new List<Process>();
|
||||
|
||||
foreach (Process other in Process.GetProcesses())
|
||||
foreach (var other in Process.GetProcesses())
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -54,12 +54,12 @@ namespace WinSW.Util
|
|||
goto Next;
|
||||
}
|
||||
|
||||
IntPtr handle = other.Handle;
|
||||
var handle = other.Handle;
|
||||
|
||||
if (NtQueryInformationProcess(
|
||||
handle,
|
||||
PROCESSINFOCLASS.ProcessBasicInformation,
|
||||
out PROCESS_BASIC_INFORMATION information,
|
||||
out var information,
|
||||
sizeof(PROCESS_BASIC_INFORMATION)) != 0)
|
||||
{
|
||||
goto Next;
|
||||
|
@ -119,7 +119,7 @@ namespace WinSW.Util
|
|||
}
|
||||
}
|
||||
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
process.Kill();
|
||||
#else
|
||||
try
|
||||
|
@ -169,7 +169,7 @@ namespace WinSW.Util
|
|||
}
|
||||
}
|
||||
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
process.Kill();
|
||||
#else
|
||||
try
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace WinSW.Util
|
|||
/// <exception cref="CommandException" />
|
||||
internal static unsafe DateTime GetLastWriteTime(this RegistryKey registryKey)
|
||||
{
|
||||
int error = RegQueryInfoKeyW(registryKey.Handle, null, null, null, null, null, null, null, null, null, null, out FILETIME lastWriteTime);
|
||||
int error = RegQueryInfoKeyW(registryKey.Handle, null, null, null, null, null, null, null, null, null, null, out var lastWriteTime);
|
||||
if (error != Errors.ERROR_SUCCESS)
|
||||
{
|
||||
Throw.Command.Win32Exception(error, "Failed to query registry key.");
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace WinSW.Util
|
|||
/// <exception cref="InvalidDataException">The required element is missing</exception>
|
||||
public static string? SingleElement(XmlNode node, string tagName, bool optional)
|
||||
{
|
||||
XmlNode? n = node.SelectSingleNode(tagName);
|
||||
var n = node.SelectSingleNode(tagName);
|
||||
if (n is null && !optional)
|
||||
{
|
||||
throw new InvalidDataException("<" + tagName + "> is missing in configuration XML");
|
||||
|
@ -36,7 +36,7 @@ namespace WinSW.Util
|
|||
/// <exception cref="InvalidDataException">The required element is missing</exception>
|
||||
public static XmlNode? SingleNode(XmlNode node, string tagName, bool optional)
|
||||
{
|
||||
XmlNode? n = node.SelectSingleNode(tagName);
|
||||
var n = node.SelectSingleNode(tagName);
|
||||
if (n is null && !optional)
|
||||
{
|
||||
throw new InvalidDataException("<" + tagName + "> is missing in configuration XML");
|
||||
|
|
|
@ -23,13 +23,13 @@ namespace WinSW.Plugins.SharedDirectoryMapper
|
|||
|
||||
public SharedDirectoryMapper(bool enableMapping, string directoryUNC, string driveLabel)
|
||||
{
|
||||
SharedDirectoryMapperConfig config = new SharedDirectoryMapperConfig(enableMapping, driveLabel, directoryUNC);
|
||||
var config = new SharedDirectoryMapperConfig(enableMapping, driveLabel, directoryUNC);
|
||||
this.entries.Add(config);
|
||||
}
|
||||
|
||||
public override void Configure(XmlServiceConfig config, XmlNode node)
|
||||
{
|
||||
XmlNodeList? mapNodes = XmlHelper.SingleNode(node, "mapping", false)!.SelectNodes("map");
|
||||
var mapNodes = XmlHelper.SingleNode(node, "mapping", false)!.SelectNodes("map");
|
||||
if (mapNodes != null)
|
||||
{
|
||||
for (int i = 0; i < mapNodes.Count; i++)
|
||||
|
@ -44,7 +44,7 @@ namespace WinSW.Plugins.SharedDirectoryMapper
|
|||
|
||||
public override void OnWrapperStarted()
|
||||
{
|
||||
foreach (SharedDirectoryMapperConfig config in this.entries)
|
||||
foreach (var config in this.entries)
|
||||
{
|
||||
string label = config.Label;
|
||||
string uncPath = config.UNCPath;
|
||||
|
@ -72,7 +72,7 @@ namespace WinSW.Plugins.SharedDirectoryMapper
|
|||
|
||||
public override void BeforeWrapperStopped()
|
||||
{
|
||||
foreach (SharedDirectoryMapperConfig config in this.entries)
|
||||
foreach (var config in this.entries)
|
||||
{
|
||||
string label = config.Label;
|
||||
if (config.EnableMapping)
|
||||
|
@ -88,7 +88,7 @@ namespace WinSW.Plugins.SharedDirectoryMapper
|
|||
|
||||
private void ThrowExtensionException(int error, string message)
|
||||
{
|
||||
Win32Exception inner = new Win32Exception(error);
|
||||
var inner = new Win32Exception(error);
|
||||
throw new ExtensionException(this.Descriptor.Id, $"{this.DisplayName}: {message} {inner.Message}", inner);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace WinSW.Tests
|
|||
{
|
||||
const string commandName = "unknown";
|
||||
|
||||
CommandLineTestResult result = Helper.ErrorTest(new[] { commandName });
|
||||
var result = Helper.ErrorTest(new[] { commandName });
|
||||
|
||||
Assert.Equal($"Unrecognized command or argument '{commandName}'\r\n\r\n", result.Error);
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ namespace WinSW.Tests
|
|||
Assert.Equal(OldCompanyName, FileVersionInfo.GetVersionInfo(inputPath).CompanyName);
|
||||
|
||||
// deny write access
|
||||
using FileStream file = File.OpenRead(inputPath);
|
||||
using var file = File.OpenRead(inputPath);
|
||||
|
||||
string outputPath = Path.GetTempFileName();
|
||||
Program.TestExecutablePath = inputPath;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using WinSW.Tests.Util;
|
||||
using Xunit;
|
||||
|
@ -15,7 +14,7 @@ namespace WinSW.Tests.Configuration
|
|||
[Fact]
|
||||
public void AllOptionsConfigShouldDeclareDefaults()
|
||||
{
|
||||
XmlServiceConfig config = Load("complete");
|
||||
var config = Load("complete");
|
||||
|
||||
Assert.Equal("myapp", config.Name);
|
||||
Assert.Equal("%BASE%\\myExecutable.exe", config.Executable);
|
||||
|
@ -26,7 +25,7 @@ namespace WinSW.Tests.Configuration
|
|||
[Fact]
|
||||
public void MinimalConfigShouldDeclareDefaults()
|
||||
{
|
||||
XmlServiceConfig config = Load("minimal");
|
||||
var config = Load("minimal");
|
||||
|
||||
Assert.Equal("myapp", config.Name);
|
||||
Assert.Equal("%BASE%\\myExecutable.exe", config.Executable);
|
||||
|
@ -41,7 +40,7 @@ namespace WinSW.Tests.Configuration
|
|||
string path = Path.Combine(directory, $@"samples\sample-{exampleName}.xml");
|
||||
Assert.True(File.Exists(path));
|
||||
|
||||
XmlDocument dom = new XmlDocument();
|
||||
var dom = new XmlDocument();
|
||||
dom.Load(path);
|
||||
return new XmlServiceConfig(dom);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace WinSW.Tests
|
|||
public void Roundtrip_Defaults()
|
||||
{
|
||||
// Roundtrip data
|
||||
Download d = new Download(From, To);
|
||||
var d = new Download(From, To);
|
||||
var config = ConfigXmlBuilder.Create(this.output)
|
||||
.WithDownload(d)
|
||||
.ToServiceConfig(true);
|
||||
|
@ -39,7 +39,7 @@ namespace WinSW.Tests
|
|||
public void Roundtrip_BasicAuth()
|
||||
{
|
||||
// Roundtrip data
|
||||
Download d = new Download(From, To, true, Download.AuthType.Basic, "aUser", "aPassword", true);
|
||||
var d = new Download(From, To, true, Download.AuthType.Basic, "aUser", "aPassword", true);
|
||||
var config = ConfigXmlBuilder.Create(this.output)
|
||||
.WithDownload(d)
|
||||
.ToServiceConfig(true);
|
||||
|
@ -57,7 +57,7 @@ namespace WinSW.Tests
|
|||
public void Roundtrip_SSPI()
|
||||
{
|
||||
// Roundtrip data
|
||||
Download d = new Download(From, To, false, Download.AuthType.Sspi);
|
||||
var d = new Download(From, To, false, Download.AuthType.Sspi);
|
||||
var config = ConfigXmlBuilder.Create(this.output)
|
||||
.WithDownload(d)
|
||||
.ToServiceConfig(true);
|
||||
|
@ -105,7 +105,7 @@ namespace WinSW.Tests
|
|||
[InlineData(false)]
|
||||
public void Download_FailOnError(bool failOnError)
|
||||
{
|
||||
Download d = new Download(From, To, failOnError);
|
||||
var d = new Download(From, To, failOnError);
|
||||
|
||||
var config = ConfigXmlBuilder.Create(this.output)
|
||||
.WithDownload(d)
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace WinSW.Tests
|
|||
|
||||
public DownloadTests()
|
||||
{
|
||||
TcpListener tcpListener = new TcpListener(IPAddress.Loopback, 0);
|
||||
var tcpListener = new TcpListener(IPAddress.Loopback, 0);
|
||||
tcpListener.Start();
|
||||
int port = ((IPEndPoint)tcpListener.LocalEndpoint).Port;
|
||||
string prefix = $"http://localhost:{port}/";
|
||||
|
@ -39,7 +39,7 @@ namespace WinSW.Tests
|
|||
|
||||
private async Task TestClientServerAsync(Func<string, string, Task> client, Action<HttpListenerContext> server, AuthenticationSchemes authenticationSchemes = AuthenticationSchemes.Anonymous, [CallerMemberName] string path = null)
|
||||
{
|
||||
HttpListener listener = new HttpListener();
|
||||
var listener = new HttpListener();
|
||||
string prefix = $"{this.globalPrefix}{path}/";
|
||||
listener.Prefixes.Add(prefix);
|
||||
listener.AuthenticationSchemes = authenticationSchemes;
|
||||
|
@ -72,7 +72,7 @@ namespace WinSW.Tests
|
|||
|
||||
async Task ListenAsync()
|
||||
{
|
||||
HttpListenerContext context = await listener.GetContextAsync();
|
||||
var context = await listener.GetContextAsync();
|
||||
try
|
||||
{
|
||||
server(context);
|
||||
|
@ -136,7 +136,7 @@ namespace WinSW.Tests
|
|||
},
|
||||
context =>
|
||||
{
|
||||
HttpListenerBasicIdentity identity = (HttpListenerBasicIdentity)context.User.Identity;
|
||||
var identity = (HttpListenerBasicIdentity)context.User.Identity;
|
||||
if (identity.Name != username || identity.Password != password)
|
||||
{
|
||||
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||
|
@ -152,8 +152,8 @@ namespace WinSW.Tests
|
|||
[Fact]
|
||||
public async Task TestHttp_IfModifiedSince_ModifiedAsync()
|
||||
{
|
||||
DateTime lastModified = DateTime.Now.TrimToSeconds();
|
||||
DateTime prevModified = lastModified.AddDays(-1);
|
||||
var lastModified = DateTime.Now.TrimToSeconds();
|
||||
var prevModified = lastModified.AddDays(-1);
|
||||
|
||||
await this.TestClientServerAsync(
|
||||
async (source, dest) =>
|
||||
|
@ -180,7 +180,7 @@ namespace WinSW.Tests
|
|||
[Fact]
|
||||
public async Task TestHttp_IfModifiedSince_NotModifiedAsync()
|
||||
{
|
||||
DateTime lastModified = DateTime.Now.TrimToSeconds();
|
||||
var lastModified = DateTime.Now.TrimToSeconds();
|
||||
|
||||
await this.TestClientServerAsync(
|
||||
async (source, dest) =>
|
||||
|
@ -210,7 +210,7 @@ namespace WinSW.Tests
|
|||
await this.TestClientServerAsync(
|
||||
async (source, dest) =>
|
||||
{
|
||||
WebException exception = await Assert.ThrowsAsync<WebException>(
|
||||
var exception = await Assert.ThrowsAsync<WebException>(
|
||||
async () => await new Download(source, dest).PerformAsync());
|
||||
|
||||
Assert.Equal(WebExceptionStatus.ProtocolError, exception.Status);
|
||||
|
|
|
@ -41,7 +41,7 @@ $@"<service>
|
|||
[Fact]
|
||||
public void LoadExtensions()
|
||||
{
|
||||
WinSWExtensionManager manager = new WinSWExtensionManager(this.serviceConfig);
|
||||
var manager = new WinSWExtensionManager(this.serviceConfig);
|
||||
manager.LoadExtensions();
|
||||
Assert.Equal(2, manager.Extensions.Count);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ $@"<service>
|
|||
[Fact]
|
||||
public void StartStopExtension()
|
||||
{
|
||||
WinSWExtensionManager manager = new WinSWExtensionManager(this.serviceConfig);
|
||||
var manager = new WinSWExtensionManager(this.serviceConfig);
|
||||
manager.LoadExtensions();
|
||||
manager.FireOnWrapperStarted();
|
||||
manager.FireBeforeWrapperStopped();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#if NETCOREAPP
|
||||
#if NET
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
@ -14,10 +14,10 @@ namespace WinSW.Tests.Extensions
|
|||
[ElevatedFact]
|
||||
public void TestMap()
|
||||
{
|
||||
using TestData data = TestData.Create();
|
||||
using var data = TestData.Create();
|
||||
|
||||
const string label = "W:";
|
||||
SharedDirectoryMapper mapper = new SharedDirectoryMapper(true, $@"\\{Environment.MachineName}\{data.name}", label);
|
||||
var mapper = new SharedDirectoryMapper(true, $@"\\{Environment.MachineName}\{data.name}", label);
|
||||
|
||||
mapper.OnWrapperStarted();
|
||||
Assert.True(Directory.Exists($@"{label}\"));
|
||||
|
@ -28,10 +28,10 @@ namespace WinSW.Tests.Extensions
|
|||
[ElevatedFact]
|
||||
public void TestDisableMapping()
|
||||
{
|
||||
using TestData data = TestData.Create();
|
||||
using var data = TestData.Create();
|
||||
|
||||
const string label = "W:";
|
||||
SharedDirectoryMapper mapper = new SharedDirectoryMapper(enableMapping: false, $@"\\{Environment.MachineName}\{data.name}", label);
|
||||
var mapper = new SharedDirectoryMapper(enableMapping: false, $@"\\{Environment.MachineName}\{data.name}", label);
|
||||
|
||||
mapper.OnWrapperStarted();
|
||||
Assert.False(Directory.Exists($@"{label}\"));
|
||||
|
@ -41,10 +41,10 @@ namespace WinSW.Tests.Extensions
|
|||
[ElevatedFact]
|
||||
public void TestMap_PathEndsWithSlash_Throws()
|
||||
{
|
||||
using TestData data = TestData.Create();
|
||||
using var data = TestData.Create();
|
||||
|
||||
const string label = "W:";
|
||||
SharedDirectoryMapper mapper = new SharedDirectoryMapper(true, $@"\\{Environment.MachineName}\{data.name}\", label);
|
||||
var mapper = new SharedDirectoryMapper(true, $@"\\{Environment.MachineName}\{data.name}\", label);
|
||||
|
||||
_ = Assert.ThrowsAny<Exception>(() => mapper.OnWrapperStarted());
|
||||
Assert.False(Directory.Exists($@"{label}\"));
|
||||
|
@ -54,10 +54,10 @@ namespace WinSW.Tests.Extensions
|
|||
[ElevatedFact]
|
||||
public void TestMap_LabelDoesNotEndWithColon_Throws()
|
||||
{
|
||||
using TestData data = TestData.Create();
|
||||
using var data = TestData.Create();
|
||||
|
||||
const string label = "W";
|
||||
SharedDirectoryMapper mapper = new SharedDirectoryMapper(true, $@"\\{Environment.MachineName}\{data.name}", label);
|
||||
var mapper = new SharedDirectoryMapper(true, $@"\\{Environment.MachineName}\{data.name}", label);
|
||||
|
||||
_ = Assert.ThrowsAny<Exception>(() => mapper.OnWrapperStarted());
|
||||
Assert.False(Directory.Exists($@"{label}\"));
|
||||
|
@ -82,7 +82,7 @@ namespace WinSW.Tests.Extensions
|
|||
|
||||
try
|
||||
{
|
||||
NativeMethods.SHARE_INFO_2 shareInfo = new NativeMethods.SHARE_INFO_2
|
||||
var shareInfo = new NativeMethods.SHARE_INFO_2
|
||||
{
|
||||
netname = name,
|
||||
type = NativeMethods.STYPE_DISKTREE | NativeMethods.STYPE_TEMPORARY,
|
||||
|
|
|
@ -405,7 +405,7 @@ $@"<service>
|
|||
<arguments>arguments</arguments>
|
||||
</service>";
|
||||
|
||||
XmlServiceConfig config = XmlServiceConfig.FromXml(seedXml);
|
||||
var config = XmlServiceConfig.FromXml(seedXml);
|
||||
|
||||
VerifyEqual(prestart, config.Prestart);
|
||||
VerifyEqual(poststart, config.Poststart);
|
||||
|
|
|
@ -33,11 +33,11 @@ $@"<service>
|
|||
/// <exception cref="Exception">Command failure</exception>
|
||||
public static string Test(string[] arguments, XmlServiceConfig config = null)
|
||||
{
|
||||
TextWriter tmpOut = Console.Out;
|
||||
TextWriter tmpError = Console.Error;
|
||||
var tmpOut = Console.Out;
|
||||
var tmpError = Console.Error;
|
||||
|
||||
using StringWriter swOut = new StringWriter();
|
||||
using StringWriter swError = new StringWriter();
|
||||
using var swOut = new StringWriter();
|
||||
using var swError = new StringWriter();
|
||||
|
||||
Console.SetOut(swOut);
|
||||
Console.SetError(swError);
|
||||
|
@ -67,11 +67,11 @@ $@"<service>
|
|||
{
|
||||
Exception exception = null;
|
||||
|
||||
TextWriter tmpOut = Console.Out;
|
||||
TextWriter tmpError = Console.Error;
|
||||
var tmpOut = Console.Out;
|
||||
var tmpError = Console.Error;
|
||||
|
||||
using StringWriter swOut = new StringWriter();
|
||||
using StringWriter swError = new StringWriter();
|
||||
using var swOut = new StringWriter();
|
||||
using var swError = new StringWriter();
|
||||
|
||||
Console.SetOut(swOut);
|
||||
Console.SetError(swError);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using WinSW.Tests.Extensions;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace WinSW.Tests.Util
|
||||
|
@ -57,7 +56,7 @@ namespace WinSW.Tests.Util
|
|||
|
||||
public string ToXmlString(bool dumpConfig = false)
|
||||
{
|
||||
StringBuilder str = new StringBuilder();
|
||||
var str = new StringBuilder();
|
||||
if (this.PrintXmlVersion)
|
||||
{
|
||||
// TODO: The encoding is generally wrong
|
||||
|
@ -121,7 +120,7 @@ namespace WinSW.Tests.Util
|
|||
|
||||
public ConfigXmlBuilder WithDownload(Download download)
|
||||
{
|
||||
StringBuilder xml = new StringBuilder();
|
||||
var xml = new StringBuilder();
|
||||
xml.Append($"<download from=\"{download.From}\" to=\"{download.To}\" failOnError=\"{download.FailOnError}\"");
|
||||
|
||||
// Authentication
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace WinSW.Tests.Util
|
|||
hr = client.SetEventCallbacks(this);
|
||||
AssertEx.Succeeded(hr);
|
||||
|
||||
IntPtr pointer = Marshal.GetIUnknownForObject(client);
|
||||
var pointer = Marshal.GetIUnknownForObject(client);
|
||||
Assert.Equal(1, Marshal.Release(pointer));
|
||||
|
||||
target = DataTarget.CreateFromDbgEng(pointer);
|
||||
|
@ -125,7 +125,7 @@ namespace WinSW.Tests.Util
|
|||
{
|
||||
using var runtime = this.target.ClrVersions.Single().CreateRuntime();
|
||||
|
||||
var module = runtime.EnumerateModules().First(module => module.Name == typeof(Program).Assembly.Location);
|
||||
ClrModule module = runtime.EnumerateModules().First(module => module.Name == typeof(Program).Assembly.Location);
|
||||
|
||||
var type = module.GetTypeByName(this.trackerType.FullName);
|
||||
var field = type.GetStaticFieldByName(this.hitsField.Name);
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace WinSW.Tests.Util
|
|||
internal static string NET461Exe => Path.Combine(ArtifactsDirectory, "publish", "WinSW.NET461.exe");
|
||||
|
||||
internal static string WinSWExe =>
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
Path.ChangeExtension(typeof(Program).Assembly.Location, ".exe");
|
||||
#else
|
||||
typeof(Program).Assembly.Location;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.Reflection;
|
||||
using WinSW.Configuration;
|
||||
using WinSW.Configuration;
|
||||
using Xunit;
|
||||
|
||||
namespace WinSW.Tests.Util
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace WinSW.Logging
|
|||
|
||||
protected override void Append(LoggingEvent loggingEvent)
|
||||
{
|
||||
IServiceEventLog? eventLog = this.provider.Locate();
|
||||
var eventLog = this.provider.Locate();
|
||||
|
||||
// We write the event iff the provider is ready
|
||||
eventLog?.WriteEntry(loggingEvent.RenderedMessage, ToEventLogEntryType(loggingEvent.Level));
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace WinSW.Logging
|
|||
{
|
||||
Console.ResetColor();
|
||||
|
||||
Level level = loggingEvent.Level;
|
||||
var level = loggingEvent.Level;
|
||||
Console.ForegroundColor =
|
||||
level >= Level.Error ? ConsoleColor.Red :
|
||||
level >= Level.Warn ? ConsoleColor.Yellow :
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace WinSW
|
|||
return TestExecutablePath;
|
||||
}
|
||||
|
||||
using Process current = Process.GetCurrentProcess();
|
||||
using var current = Process.GetCurrentProcess();
|
||||
return current.MainModule!.FileName!;
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ namespace WinSW
|
|||
Console.SetError(new StreamWriter(stderr) { AutoFlush = true });
|
||||
}
|
||||
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
args = args[4..];
|
||||
#else
|
||||
string[] oldArgs = args;
|
||||
|
@ -116,15 +116,13 @@ namespace WinSW
|
|||
XmlServiceConfig config = null!;
|
||||
try
|
||||
{
|
||||
config = LoadConfig(pathToConfig);
|
||||
config = LoadConfigAndInitLoggers(pathToConfig, false);
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
Throw.Command.Exception("The specified command or file was not found.");
|
||||
}
|
||||
|
||||
InitLoggers(config, enableConsoleLogging: false);
|
||||
|
||||
Log.Debug("Starting WinSW in service mode.");
|
||||
|
||||
AutoRefresh(config);
|
||||
|
@ -141,9 +139,9 @@ namespace WinSW
|
|||
}),
|
||||
};
|
||||
|
||||
using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
|
||||
using (var identity = WindowsIdentity.GetCurrent())
|
||||
{
|
||||
WindowsPrincipal principal = new WindowsPrincipal(identity);
|
||||
var principal = new WindowsPrincipal(identity);
|
||||
if (principal.IsInRole(new SecurityIdentifier(WellKnownSidType.ServiceSid, null)) ||
|
||||
principal.IsInRole(new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null)) ||
|
||||
principal.IsInRole(new SecurityIdentifier(WellKnownSidType.LocalServiceSid, null)) ||
|
||||
|
@ -420,8 +418,7 @@ namespace WinSW
|
|||
|
||||
void Install(string? pathToConfig, bool noElevate, string? username, string? password)
|
||||
{
|
||||
XmlServiceConfig config = LoadConfig(pathToConfig);
|
||||
InitLoggers(config, enableConsoleLogging: true);
|
||||
var config = LoadConfigAndInitLoggers(pathToConfig, true);
|
||||
|
||||
if (!elevated)
|
||||
{
|
||||
|
@ -431,7 +428,7 @@ namespace WinSW
|
|||
|
||||
Log.Info($"Installing service '{config.Format()}'...");
|
||||
|
||||
using ServiceManager scm = ServiceManager.Open(ServiceManagerAccess.CreateService);
|
||||
using var scm = ServiceManager.Open(ServiceManagerAccess.CreateService);
|
||||
|
||||
if (scm.ServiceExists(config.Name))
|
||||
{
|
||||
|
@ -468,7 +465,7 @@ namespace WinSW
|
|||
Security.AddServiceLogonRight(ref username);
|
||||
}
|
||||
|
||||
using Service sc = scm.CreateService(
|
||||
using var sc = scm.CreateService(
|
||||
config.Name,
|
||||
config.DisplayName,
|
||||
config.StartMode,
|
||||
|
@ -483,7 +480,7 @@ namespace WinSW
|
|||
sc.SetDescription(description);
|
||||
}
|
||||
|
||||
SC_ACTION[] actions = config.FailureActions;
|
||||
var actions = config.FailureActions;
|
||||
if (actions.Length > 0)
|
||||
{
|
||||
sc.SetFailureActions(config.ResetFailureAfter, actions);
|
||||
|
@ -545,8 +542,7 @@ namespace WinSW
|
|||
|
||||
void Uninstall(string? pathToConfig, bool noElevate)
|
||||
{
|
||||
XmlServiceConfig config = LoadConfig(pathToConfig);
|
||||
InitLoggers(config, enableConsoleLogging: true);
|
||||
var config = LoadConfigAndInitLoggers(pathToConfig, true);
|
||||
|
||||
if (!elevated)
|
||||
{
|
||||
|
@ -556,10 +552,10 @@ namespace WinSW
|
|||
|
||||
Log.Info($"Uninstalling service '{config.Format()}'...");
|
||||
|
||||
using ServiceManager scm = ServiceManager.Open(ServiceManagerAccess.Connect);
|
||||
using var scm = ServiceManager.Open(ServiceManagerAccess.Connect);
|
||||
try
|
||||
{
|
||||
using Service sc = scm.OpenService(config.Name);
|
||||
using var sc = scm.OpenService(config.Name);
|
||||
|
||||
if (sc.Status != ServiceControllerStatus.Stopped)
|
||||
{
|
||||
|
@ -595,8 +591,7 @@ namespace WinSW
|
|||
|
||||
void Start(string? pathToConfig, bool noElevate, bool noWait, CancellationToken ct)
|
||||
{
|
||||
XmlServiceConfig config = LoadConfig(pathToConfig);
|
||||
InitLoggers(config, enableConsoleLogging: true);
|
||||
var config = LoadConfigAndInitLoggers(pathToConfig, true);
|
||||
|
||||
if (!elevated)
|
||||
{
|
||||
|
@ -641,8 +636,7 @@ namespace WinSW
|
|||
|
||||
void Stop(string? pathToConfig, bool noElevate, bool noWait, bool force, CancellationToken ct)
|
||||
{
|
||||
XmlServiceConfig config = LoadConfig(pathToConfig);
|
||||
InitLoggers(config, enableConsoleLogging: true);
|
||||
var config = LoadConfigAndInitLoggers(pathToConfig, true);
|
||||
|
||||
if (!elevated)
|
||||
{
|
||||
|
@ -695,8 +689,7 @@ namespace WinSW
|
|||
|
||||
void Restart(string? pathToConfig, bool noElevate, bool force, CancellationToken ct)
|
||||
{
|
||||
XmlServiceConfig config = LoadConfig(pathToConfig);
|
||||
InitLoggers(config, enableConsoleLogging: true);
|
||||
var config = LoadConfigAndInitLoggers(pathToConfig, true);
|
||||
|
||||
if (!elevated)
|
||||
{
|
||||
|
@ -758,7 +751,7 @@ namespace WinSW
|
|||
|
||||
if (startedDependentServices != null)
|
||||
{
|
||||
foreach (ServiceController service in startedDependentServices)
|
||||
foreach (var service in startedDependentServices)
|
||||
{
|
||||
if (service.Status == ServiceControllerStatus.Stopped)
|
||||
{
|
||||
|
@ -773,8 +766,7 @@ namespace WinSW
|
|||
|
||||
void RestartSelf(string? pathToConfig)
|
||||
{
|
||||
XmlServiceConfig config = LoadConfig(pathToConfig);
|
||||
InitLoggers(config, enableConsoleLogging: true);
|
||||
var config = LoadConfigAndInitLoggers(pathToConfig, true);
|
||||
|
||||
if (!elevated)
|
||||
{
|
||||
|
@ -794,7 +786,7 @@ namespace WinSW
|
|||
IntPtr.Zero,
|
||||
null,
|
||||
default,
|
||||
out ProcessApis.PROCESS_INFORMATION processInfo))
|
||||
out var processInfo))
|
||||
{
|
||||
Throw.Command.Win32Exception("Failed to invoke restart.");
|
||||
}
|
||||
|
@ -805,8 +797,7 @@ namespace WinSW
|
|||
|
||||
static int Status(string? pathToConfig)
|
||||
{
|
||||
XmlServiceConfig config = LoadConfig(pathToConfig);
|
||||
InitLoggers(config, enableConsoleLogging: true);
|
||||
var config = LoadConfigAndInitLoggers(pathToConfig, true);
|
||||
|
||||
using var svc = new ServiceController(config.Name);
|
||||
try
|
||||
|
@ -838,8 +829,7 @@ namespace WinSW
|
|||
|
||||
void Test(string? pathToConfig, bool noElevate, bool noBreak)
|
||||
{
|
||||
XmlServiceConfig config = LoadConfig(pathToConfig);
|
||||
InitLoggers(config, enableConsoleLogging: true);
|
||||
var config = LoadConfigAndInitLoggers(pathToConfig, true);
|
||||
|
||||
if (!elevated)
|
||||
{
|
||||
|
@ -849,7 +839,7 @@ namespace WinSW
|
|||
|
||||
AutoRefresh(config);
|
||||
|
||||
using WrapperService wsvc = new WrapperService(config);
|
||||
using var wsvc = new WrapperService(config);
|
||||
wsvc.RaiseOnStart(args);
|
||||
try
|
||||
{
|
||||
|
@ -860,7 +850,7 @@ namespace WinSW
|
|||
}
|
||||
else
|
||||
{
|
||||
using ManualResetEvent evt = new ManualResetEvent(false);
|
||||
using var evt = new ManualResetEvent(false);
|
||||
|
||||
Console.WriteLine("Press Ctrl+C to stop the service...");
|
||||
Console.CancelKeyPress += CancelKeyPress;
|
||||
|
@ -883,8 +873,7 @@ namespace WinSW
|
|||
|
||||
void Refresh(string? pathToConfig, bool noElevate)
|
||||
{
|
||||
XmlServiceConfig config = LoadConfig(pathToConfig);
|
||||
InitLoggers(config, enableConsoleLogging: true);
|
||||
var config = LoadConfigAndInitLoggers(pathToConfig, true);
|
||||
|
||||
if (!elevated)
|
||||
{
|
||||
|
@ -900,7 +889,7 @@ namespace WinSW
|
|||
if (all)
|
||||
{
|
||||
using var scm = ServiceManager.Open(ServiceManagerAccess.EnumerateService);
|
||||
(IntPtr services, int count) = scm.EnumerateServices();
|
||||
(var services, int count) = scm.EnumerateServices();
|
||||
try
|
||||
{
|
||||
int prevProcessId = -1;
|
||||
|
@ -915,7 +904,7 @@ namespace WinSW
|
|||
{
|
||||
if (prevProcessId >= 0)
|
||||
{
|
||||
using Process process = Process.GetProcessById(prevProcessId);
|
||||
using var process = Process.GetProcessById(prevProcessId);
|
||||
Draw(process, string.Empty, false);
|
||||
}
|
||||
}
|
||||
|
@ -926,7 +915,7 @@ namespace WinSW
|
|||
|
||||
if (prevProcessId >= 0)
|
||||
{
|
||||
using Process process = Process.GetProcessById(prevProcessId);
|
||||
using var process = Process.GetProcessById(prevProcessId);
|
||||
Draw(process, string.Empty, true);
|
||||
}
|
||||
}
|
||||
|
@ -937,15 +926,15 @@ namespace WinSW
|
|||
}
|
||||
else
|
||||
{
|
||||
XmlServiceConfig config = LoadConfig(pathToConfig);
|
||||
var config = LoadConfigAndInitLoggers(pathToConfig, true);
|
||||
|
||||
using ServiceManager scm = ServiceManager.Open(ServiceManagerAccess.Connect);
|
||||
using Service sc = scm.OpenService(config.Name, ServiceAccess.QueryStatus);
|
||||
using var scm = ServiceManager.Open(ServiceManagerAccess.Connect);
|
||||
using var sc = scm.OpenService(config.Name, ServiceAccess.QueryStatus);
|
||||
|
||||
int processId = sc.ProcessId;
|
||||
if (processId >= 0)
|
||||
{
|
||||
using Process process = Process.GetProcessById(processId);
|
||||
using var process = Process.GetProcessById(processId);
|
||||
Draw(process, string.Empty, true);
|
||||
}
|
||||
}
|
||||
|
@ -972,11 +961,11 @@ namespace WinSW
|
|||
|
||||
Console.WriteLine(process.Format());
|
||||
|
||||
List<Process> children = process.GetChildren();
|
||||
var children = process.GetChildren();
|
||||
int count = children.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
using Process child = children[i];
|
||||
using var child = children[i];
|
||||
Draw(child, indentation, i == count - 1);
|
||||
}
|
||||
}
|
||||
|
@ -984,7 +973,7 @@ namespace WinSW
|
|||
|
||||
void DevKill(string? pathToConfig, bool noElevate)
|
||||
{
|
||||
XmlServiceConfig config = LoadConfig(pathToConfig);
|
||||
var config = LoadConfigAndInitLoggers(pathToConfig, true);
|
||||
|
||||
if (!elevated)
|
||||
{
|
||||
|
@ -992,13 +981,13 @@ namespace WinSW
|
|||
return;
|
||||
}
|
||||
|
||||
using ServiceManager scm = ServiceManager.Open();
|
||||
using Service sc = scm.OpenService(config.Name);
|
||||
using var scm = ServiceManager.Open();
|
||||
using var sc = scm.OpenService(config.Name);
|
||||
|
||||
int processId = sc.ProcessId;
|
||||
if (processId >= 0)
|
||||
{
|
||||
using Process process = Process.GetProcessById(processId);
|
||||
using var process = Process.GetProcessById(processId);
|
||||
|
||||
process.StopDescendants(config.StopTimeoutInMs);
|
||||
}
|
||||
|
@ -1007,7 +996,7 @@ namespace WinSW
|
|||
static unsafe void DevList()
|
||||
{
|
||||
using var scm = ServiceManager.Open(ServiceManagerAccess.EnumerateService);
|
||||
(IntPtr services, int count) = scm.EnumerateServices();
|
||||
(var services, int count) = scm.EnumerateServices();
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
|
@ -1058,7 +1047,7 @@ namespace WinSW
|
|||
" " + (stderrName ?? NoPipe) +
|
||||
commandLine.Remove(commandLine.IndexOf(exe), exe.Length).TrimStart('"');
|
||||
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo
|
||||
var startInfo = new ProcessStartInfo
|
||||
{
|
||||
UseShellExecute = true,
|
||||
Verb = "runas",
|
||||
|
@ -1069,7 +1058,7 @@ namespace WinSW
|
|||
|
||||
try
|
||||
{
|
||||
using Process elevated = Process.Start(startInfo)!;
|
||||
using var elevated = Process.Start(startInfo)!;
|
||||
|
||||
if (stdinName is not null)
|
||||
{
|
||||
|
@ -1106,9 +1095,9 @@ namespace WinSW
|
|||
return;
|
||||
}
|
||||
|
||||
DateTime fileLastWriteTime = File.GetLastWriteTime(config.FullPath);
|
||||
var fileLastWriteTime = File.GetLastWriteTime(config.FullPath);
|
||||
|
||||
using RegistryKey? registryKey = Registry.LocalMachine
|
||||
using var registryKey = Registry.LocalMachine
|
||||
.OpenSubKey("SYSTEM")?
|
||||
.OpenSubKey("CurrentControlSet")?
|
||||
.OpenSubKey("Services")?
|
||||
|
@ -1119,7 +1108,7 @@ namespace WinSW
|
|||
return;
|
||||
}
|
||||
|
||||
DateTime registryLastWriteTime = registryKey.GetLastWriteTime();
|
||||
var registryLastWriteTime = registryKey.GetLastWriteTime();
|
||||
|
||||
if (fileLastWriteTime > registryLastWriteTime)
|
||||
{
|
||||
|
@ -1129,16 +1118,16 @@ namespace WinSW
|
|||
|
||||
static void DoRefresh(XmlServiceConfig config)
|
||||
{
|
||||
using ServiceManager scm = ServiceManager.Open(ServiceManagerAccess.Connect);
|
||||
using var scm = ServiceManager.Open(ServiceManagerAccess.Connect);
|
||||
try
|
||||
{
|
||||
using Service sc = scm.OpenService(config.Name);
|
||||
using var sc = scm.OpenService(config.Name);
|
||||
|
||||
sc.ChangeConfig(config.DisplayName, config.StartMode, config.ServiceDependencies);
|
||||
|
||||
sc.SetDescription(config.Description);
|
||||
|
||||
SC_ACTION[] actions = config.FailureActions;
|
||||
var actions = config.FailureActions;
|
||||
if (actions.Length > 0)
|
||||
{
|
||||
sc.SetFailureActions(config.ResetFailureAfter, actions);
|
||||
|
@ -1173,43 +1162,55 @@ namespace WinSW
|
|||
}
|
||||
|
||||
/// <exception cref="FileNotFoundException" />
|
||||
private static XmlServiceConfig LoadConfig(string? path)
|
||||
private static XmlServiceConfig LoadConfigAndInitLoggers(string? path, bool enableConsoleLogging)
|
||||
{
|
||||
if (TestConfig != null)
|
||||
{
|
||||
return TestConfig;
|
||||
}
|
||||
|
||||
if (path != null)
|
||||
// TODO: Make logging levels configurable
|
||||
var 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
|
||||
var consoleLogLevel = Level.Info;
|
||||
var eventLogLevel = Level.Warn;
|
||||
|
||||
// console log
|
||||
if (enableConsoleLogging)
|
||||
{
|
||||
return new XmlServiceConfig(path);
|
||||
var consoleAppender = new WinSWConsoleAppender
|
||||
{
|
||||
Name = "Wrapper console log",
|
||||
Threshold = consoleLogLevel,
|
||||
Layout = new PatternLayout("%date{ABSOLUTE} - %message%newline"),
|
||||
};
|
||||
consoleAppender.ActivateOptions();
|
||||
|
||||
BasicConfigurator.Configure(
|
||||
#if NET
|
||||
LogManager.GetRepository(Assembly.GetExecutingAssembly()),
|
||||
#endif
|
||||
consoleAppender);
|
||||
}
|
||||
|
||||
XmlServiceConfig config;
|
||||
if (path != null)
|
||||
{
|
||||
config = new XmlServiceConfig(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
path = Path.ChangeExtension(ExecutablePath, ".xml");
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
throw new FileNotFoundException("Unable to locate " + Path.GetFileNameWithoutExtension(path) + ".xml file within executable directory.");
|
||||
}
|
||||
|
||||
return new XmlServiceConfig(path);
|
||||
config = new XmlServiceConfig(path);
|
||||
}
|
||||
|
||||
private static void InitLoggers(XmlServiceConfig config, bool enableConsoleLogging)
|
||||
{
|
||||
if (XmlServiceConfig.TestConfig != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 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;
|
||||
Level eventLogLevel = Level.Warn;
|
||||
|
||||
List<IAppender> appenders = new List<IAppender>();
|
||||
|
||||
// .wrapper.log
|
||||
string wrapperLogPath = Path.Combine(config.LogDirectory, config.BaseName + ".wrapper.log");
|
||||
var wrapperLog = new FileAppender
|
||||
|
@ -1223,20 +1224,6 @@ namespace WinSW
|
|||
Layout = new PatternLayout("%date %-5level - %message%newline"),
|
||||
};
|
||||
wrapperLog.ActivateOptions();
|
||||
appenders.Add(wrapperLog);
|
||||
|
||||
// console log
|
||||
if (enableConsoleLogging)
|
||||
{
|
||||
var consoleAppender = new WinSWConsoleAppender
|
||||
{
|
||||
Name = "Wrapper console log",
|
||||
Threshold = consoleLogLevel,
|
||||
Layout = new PatternLayout("%date{ABSOLUTE} - %message%newline"),
|
||||
};
|
||||
consoleAppender.ActivateOptions();
|
||||
appenders.Add(consoleAppender);
|
||||
}
|
||||
|
||||
// event log
|
||||
var systemEventLogger = new ServiceEventLogAppender(WrapperService.eventLogProvider)
|
||||
|
@ -1245,20 +1232,22 @@ namespace WinSW
|
|||
Threshold = eventLogLevel,
|
||||
};
|
||||
systemEventLogger.ActivateOptions();
|
||||
appenders.Add(systemEventLogger);
|
||||
|
||||
BasicConfigurator.Configure(
|
||||
#if NETCOREAPP
|
||||
LogManager.GetRepository(System.Reflection.Assembly.GetExecutingAssembly()),
|
||||
#if NET
|
||||
LogManager.GetRepository(Assembly.GetExecutingAssembly()),
|
||||
#endif
|
||||
appenders.ToArray());
|
||||
wrapperLog,
|
||||
systemEventLogger);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/// <exception cref="CommandException" />
|
||||
internal static bool IsProcessElevated()
|
||||
{
|
||||
IntPtr process = ProcessApis.GetCurrentProcess();
|
||||
if (!ProcessApis.OpenProcessToken(process, TokenAccessLevels.Read, out IntPtr token))
|
||||
var process = ProcessApis.GetCurrentProcess();
|
||||
if (!ProcessApis.OpenProcessToken(process, TokenAccessLevels.Read, out var token))
|
||||
{
|
||||
Throw.Command.Win32Exception("Failed to open process token.");
|
||||
}
|
||||
|
@ -1270,7 +1259,7 @@ namespace WinSW
|
|||
if (!SecurityApis.GetTokenInformation(
|
||||
token,
|
||||
SecurityApis.TOKEN_INFORMATION_CLASS.TokenElevation,
|
||||
out SecurityApis.TOKEN_ELEVATION elevation,
|
||||
out var elevation,
|
||||
sizeof(SecurityApis.TOKEN_ELEVATION),
|
||||
out _))
|
||||
{
|
||||
|
@ -1288,10 +1277,10 @@ namespace WinSW
|
|||
|
||||
private static string ReadPassword()
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
var buf = new StringBuilder();
|
||||
while (true)
|
||||
{
|
||||
ConsoleKeyInfo key = Console.ReadKey(true);
|
||||
var key = Console.ReadKey(true);
|
||||
if (key.Key == ConsoleKey.Enter)
|
||||
{
|
||||
return buf.ToString();
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace WinSW
|
|||
/// <exception cref="TimeoutException" />
|
||||
internal static void WaitForStatus(this ServiceController serviceController, ServiceControllerStatus desiredStatus, ServiceControllerStatus pendingStatus, CancellationToken ct)
|
||||
{
|
||||
TimeSpan timeout = new TimeSpan(TimeSpan.TicksPerSecond);
|
||||
var timeout = new TimeSpan(TimeSpan.TicksPerSecond);
|
||||
for (; ; )
|
||||
{
|
||||
try
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace WinSW
|
|||
private static readonly int additionalStopTimeout = 1_000;
|
||||
|
||||
private static readonly ILog Log = LogManager.GetLogger(
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
Assembly.GetExecutingAssembly(),
|
||||
#endif
|
||||
"WinSW");
|
||||
|
@ -71,7 +71,7 @@ namespace WinSW
|
|||
/// </summary>
|
||||
private void HandleFileCopies()
|
||||
{
|
||||
var file = this.config.BasePath + ".copies";
|
||||
string? file = this.config.BasePath + ".copies";
|
||||
if (!File.Exists(file))
|
||||
{
|
||||
return; // nothing to handle
|
||||
|
@ -128,7 +128,7 @@ namespace WinSW
|
|||
Directory.CreateDirectory(logDirectory);
|
||||
}
|
||||
|
||||
LogHandler logAppender = this.config.LogHandler;
|
||||
var logAppender = this.config.LogHandler;
|
||||
logAppender.EventLogger = this;
|
||||
return logAppender;
|
||||
}
|
||||
|
@ -264,11 +264,11 @@ namespace WinSW
|
|||
this.HandleFileCopies();
|
||||
|
||||
// handle downloads
|
||||
List<Download> downloads = this.config.Downloads;
|
||||
Task[] tasks = new Task[downloads.Count];
|
||||
var downloads = this.config.Downloads;
|
||||
var tasks = new Task[downloads.Count];
|
||||
for (int i = 0; i < downloads.Count; i++)
|
||||
{
|
||||
Download download = downloads[i];
|
||||
var download = downloads[i];
|
||||
string downloadMessage = $"Downloading: {download.From} to {download.To}. failOnError={download.FailOnError.ToString()}";
|
||||
Log.Info(downloadMessage);
|
||||
tasks[i] = download.PerformAsync();
|
||||
|
@ -280,14 +280,14 @@ namespace WinSW
|
|||
}
|
||||
catch (AggregateException e)
|
||||
{
|
||||
List<Exception> exceptions = new List<Exception>(e.InnerExceptions.Count);
|
||||
var exceptions = new List<Exception>(e.InnerExceptions.Count);
|
||||
for (int i = 0; i < tasks.Length; i++)
|
||||
{
|
||||
if (tasks[i].IsFaulted)
|
||||
{
|
||||
Download download = downloads[i];
|
||||
var download = downloads[i];
|
||||
string errorMessage = $"Failed to download {download.From} to {download.To}";
|
||||
AggregateException exception = tasks[i].Exception!;
|
||||
var exception = tasks[i].Exception!;
|
||||
Log.Error(errorMessage, exception);
|
||||
|
||||
// TODO: move this code into the download logic
|
||||
|
@ -301,13 +301,13 @@ namespace WinSW
|
|||
throw new AggregateException(exceptions);
|
||||
}
|
||||
|
||||
ProcessCommand prestart = this.config.Prestart;
|
||||
var prestart = this.config.Prestart;
|
||||
string? prestartExecutable = prestart.Executable;
|
||||
if (prestartExecutable != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using Process process = this.StartProcess(prestartExecutable, prestart.Arguments, prestart.CreateLogHandler());
|
||||
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);
|
||||
|
@ -326,17 +326,17 @@ namespace WinSW
|
|||
this.ExtensionManager.LoadExtensions();
|
||||
this.ExtensionManager.FireOnWrapperStarted();
|
||||
|
||||
LogHandler executableLogHandler = this.CreateExecutableLogHandler();
|
||||
var executableLogHandler = this.CreateExecutableLogHandler();
|
||||
this.process = this.StartProcess(this.config.Executable, startArguments, executableLogHandler, this.OnMainProcessExited);
|
||||
this.ExtensionManager.FireOnProcessStarted(this.process);
|
||||
|
||||
ProcessCommand poststart = this.config.Poststart;
|
||||
var poststart = this.config.Poststart;
|
||||
string? poststartExecutable = poststart.Executable;
|
||||
if (poststartExecutable != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using Process process = StartProcessLocked();
|
||||
using var process = StartProcessLocked();
|
||||
this.WaitForProcessToExit(process);
|
||||
this.LogExited($"Post-start process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
|
||||
process.StopDescendants(additionalStopTimeout);
|
||||
|
@ -362,13 +362,13 @@ namespace WinSW
|
|||
/// </summary>
|
||||
private void DoStop()
|
||||
{
|
||||
ProcessCommand prestop = this.config.Prestop;
|
||||
var prestop = this.config.Prestop;
|
||||
string? prestopExecutable = prestop.Executable;
|
||||
if (prestopExecutable != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using Process process = StartProcessLocked(prestopExecutable, prestop.Arguments, prestop.CreateLogHandler());
|
||||
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);
|
||||
|
@ -387,7 +387,7 @@ namespace WinSW
|
|||
string? stopArguments = this.config.StopArguments;
|
||||
if (stopExecutable is null && stopArguments is null)
|
||||
{
|
||||
Process process = this.process;
|
||||
var process = this.process;
|
||||
Log.Debug("ProcessKill " + process.Id);
|
||||
bool? result = process.Stop(this.config.StopTimeoutInMs);
|
||||
this.LogMinimal($"Child process '{process.Format()}' " + result switch
|
||||
|
@ -408,7 +408,7 @@ namespace WinSW
|
|||
try
|
||||
{
|
||||
// TODO: Redirect logging to Log4Net once https://github.com/kohsuke/winsw/pull/213 is integrated
|
||||
using Process stopProcess = StartProcessLocked(stopExecutable, stopArguments);
|
||||
using var stopProcess = StartProcessLocked(stopExecutable, stopArguments);
|
||||
|
||||
Log.Debug("WaitForProcessToExit " + this.process.Id + "+" + stopProcess.Id);
|
||||
this.WaitForProcessToExit(stopProcess);
|
||||
|
@ -425,13 +425,13 @@ namespace WinSW
|
|||
}
|
||||
}
|
||||
|
||||
ProcessCommand poststop = this.config.Poststop;
|
||||
var poststop = this.config.Poststop;
|
||||
string? poststopExecutable = poststop.Executable;
|
||||
if (poststopExecutable != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using Process process = StartProcessLocked(poststopExecutable, poststop.Arguments, poststop.CreateLogHandler());
|
||||
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);
|
||||
|
@ -477,13 +477,13 @@ namespace WinSW
|
|||
private void AcceptPreshutdown()
|
||||
{
|
||||
const string acceptedCommandsFieldName =
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
"_acceptedCommands";
|
||||
#else
|
||||
"acceptedCommands";
|
||||
#endif
|
||||
|
||||
FieldInfo? acceptedCommandsField = typeof(ServiceBase).GetField(acceptedCommandsFieldName, BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
var acceptedCommandsField = typeof(ServiceBase).GetField(acceptedCommandsFieldName, BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
if (acceptedCommandsField is null)
|
||||
{
|
||||
throw new MissingFieldException(nameof(ServiceBase), acceptedCommandsFieldName);
|
||||
|
@ -501,8 +501,8 @@ namespace WinSW
|
|||
|
||||
private void SignalStopped()
|
||||
{
|
||||
using ServiceManager scm = ServiceManager.Open();
|
||||
using Service sc = scm.OpenService(this.ServiceName, ServiceApis.ServiceAccess.QueryStatus);
|
||||
using var scm = ServiceManager.Open();
|
||||
using var sc = scm.OpenService(this.ServiceName, ServiceApis.ServiceAccess.QueryStatus);
|
||||
|
||||
sc.SetStatus(this.ServiceHandle, ServiceControllerStatus.Stopped);
|
||||
}
|
||||
|
@ -549,16 +549,16 @@ namespace WinSW
|
|||
RedirectStandardError = logHandler?.ErrFileDisabled == false,
|
||||
};
|
||||
|
||||
Dictionary<string, string> environment = this.config.EnvironmentVariables;
|
||||
var environment = this.config.EnvironmentVariables;
|
||||
if (environment.Count > 0)
|
||||
{
|
||||
var newEnvironment =
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
startInfo.Environment;
|
||||
#else
|
||||
startInfo.EnvironmentVariables;
|
||||
#endif
|
||||
foreach (KeyValuePair<string, string> pair in environment)
|
||||
foreach (var pair in environment)
|
||||
{
|
||||
newEnvironment[pair.Key] = pair.Value;
|
||||
}
|
||||
|
@ -607,7 +607,7 @@ namespace WinSW
|
|||
{
|
||||
process.Exited += (sender, _) =>
|
||||
{
|
||||
Process process = (Process)sender!;
|
||||
var process = (Process)sender!;
|
||||
|
||||
if (!process.EnableRaisingEvents)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue