Refactoring: cleanup the codestyle, convert vars to properties, etc.

Signed-off-by: Oleg Nenashev <o.v.nenashev@gmail.com>
pull/75/head
Oleg Nenashev 2015-01-31 02:26:28 +03:00
parent 0105fe5214
commit 6fcebfa0e2
13 changed files with 217 additions and 303 deletions

View File

@ -1,19 +1,21 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
// ReSharper disable InconsistentNaming
namespace winsw
{
class ServiceManager : IDisposable
{
private IntPtr Handle;
private IntPtr _handle;
public ServiceManager()
{
Handle = Advapi32.OpenSCManager(null, null, (uint)SCM_ACCESS.SC_MANAGER_ALL_ACCESS);
if (Handle == IntPtr.Zero)
_handle = Advapi32.OpenSCManager(null, null, (uint)SCM_ACCESS.SC_MANAGER_ALL_ACCESS);
if (_handle == IntPtr.Zero)
{
throw new Exception(String.Format("Error connecting to Service Control Manager. Error provided was: 0x{0:X}", Marshal.GetLastWin32Error()));
}
@ -21,7 +23,7 @@ namespace winsw
public Service Open(string serviceName)
{
IntPtr svcHandle = Advapi32.OpenService(Handle, serviceName, (int)SERVICE_ACCESS.SERVICE_ALL_ACCESS);
IntPtr svcHandle = Advapi32.OpenService(_handle, serviceName, (int)SERVICE_ACCESS.SERVICE_ALL_ACCESS);
if (svcHandle == IntPtr.Zero)
{
throw new Exception(String.Format("Error opening service for modifying. Error returned was: 0x{0:X}", Marshal.GetLastWin32Error()));
@ -31,9 +33,9 @@ namespace winsw
public void Dispose()
{
if (Handle != IntPtr.Zero)
Advapi32.CloseServiceHandle(Handle);
Handle = IntPtr.Zero;
if (_handle != IntPtr.Zero)
Advapi32.CloseServiceHandle(_handle);
_handle = IntPtr.Zero;
}
}
@ -48,10 +50,14 @@ namespace winsw
public void ChangeConfig(TimeSpan failureResetPeriod, List<SC_ACTION> actions)
{
SERVICE_FAILURE_ACTIONS sfa = new SERVICE_FAILURE_ACTIONS();
sfa.dwResetPeriod = (int)failureResetPeriod.TotalSeconds;
sfa.lpRebootMsg = ""; // delete message
sfa.lpCommand = ""; // delete the command to run
SERVICE_FAILURE_ACTIONS sfa = new SERVICE_FAILURE_ACTIONS
{
dwResetPeriod = (int) failureResetPeriod.TotalSeconds,
lpRebootMsg = "",
lpCommand = ""
};
// delete message
// delete the command to run
int len = Marshal.SizeOf(typeof(SC_ACTION));
@ -83,15 +89,15 @@ namespace winsw
static class LogonAsAService
{
public static void AddLogonAsAServiceRight(string Username)
public static void AddLogonAsAServiceRight(string username)
{
//Needs to be at least XP or 2003 server
//https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx
System.OperatingSystem osInfo = System.Environment.OSVersion;
OperatingSystem osInfo = Environment.OSVersion;
if (osInfo.Version.Major >= 5 && osInfo.Version.Minor >= 1)
{
var newuser = GetLocalAccountIfLocalAccount(Username);
var newuser = GetLocalAccountIfLocalAccount(username);
//Trace.WriteLine("Username for Logon as A Service: " + newuser);
long rightexitcode = SetRight(newuser, PrivlegeRights.SeServiceLogonRight.ToString());
if (rightexitcode != 0)
@ -108,17 +114,19 @@ namespace winsw
private static string GetDomain(string s)
{
int stop = s.IndexOf("\\");
int stop = s.IndexOf("\\", StringComparison.Ordinal);
if (stop >= 0)
return s.Substring(0, stop);
else
return null;
}
private static string GetLogin(string s)
{
int stop = s.IndexOf("\\");
int stop = s.IndexOf("\\", StringComparison.Ordinal);
return (stop > -1) ? s.Substring(stop + 1, s.Length - stop - 1) : s;
}
private static string GetLocalAccountIfLocalAccount(string username)
{
var machinename = Environment.MachineName;
@ -174,34 +182,36 @@ namespace winsw
//initialize an empty unicode-string
LSA_UNICODE_STRING systemName = new LSA_UNICODE_STRING();
//combine all policies
int access = (int)(
LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN |
LSA_AccessPolicy.POLICY_CREATE_ACCOUNT |
LSA_AccessPolicy.POLICY_CREATE_PRIVILEGE |
LSA_AccessPolicy.POLICY_CREATE_SECRET |
LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION |
LSA_AccessPolicy.POLICY_LOOKUP_NAMES |
LSA_AccessPolicy.POLICY_NOTIFICATION |
LSA_AccessPolicy.POLICY_SERVER_ADMIN |
LSA_AccessPolicy.POLICY_SET_AUDIT_REQUIREMENTS |
LSA_AccessPolicy.POLICY_SET_DEFAULT_QUOTA_LIMITS |
LSA_AccessPolicy.POLICY_TRUST_ADMIN |
LSA_AccessPolicy.POLICY_VIEW_AUDIT_INFORMATION |
LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION
);
const int access = (int)(
LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN |
LSA_AccessPolicy.POLICY_CREATE_ACCOUNT |
LSA_AccessPolicy.POLICY_CREATE_PRIVILEGE |
LSA_AccessPolicy.POLICY_CREATE_SECRET |
LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION |
LSA_AccessPolicy.POLICY_LOOKUP_NAMES |
LSA_AccessPolicy.POLICY_NOTIFICATION |
LSA_AccessPolicy.POLICY_SERVER_ADMIN |
LSA_AccessPolicy.POLICY_SET_AUDIT_REQUIREMENTS |
LSA_AccessPolicy.POLICY_SET_DEFAULT_QUOTA_LIMITS |
LSA_AccessPolicy.POLICY_TRUST_ADMIN |
LSA_AccessPolicy.POLICY_VIEW_AUDIT_INFORMATION |
LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION
);
//initialize a pointer for the policy handle
IntPtr policyHandle = IntPtr.Zero;
//these attributes are not used, but LsaOpenPolicy wants them to exists
LSA_OBJECT_ATTRIBUTES ObjectAttributes = new LSA_OBJECT_ATTRIBUTES();
ObjectAttributes.Length = 0;
ObjectAttributes.RootDirectory = IntPtr.Zero;
ObjectAttributes.Attributes = 0;
ObjectAttributes.SecurityDescriptor = IntPtr.Zero;
ObjectAttributes.SecurityQualityOfService = IntPtr.Zero;
LSA_OBJECT_ATTRIBUTES objectAttributes = new LSA_OBJECT_ATTRIBUTES
{
Length = 0,
RootDirectory = IntPtr.Zero,
Attributes = 0,
SecurityDescriptor = IntPtr.Zero,
SecurityQualityOfService = IntPtr.Zero
};
//get a policy handle
uint resultPolicy = Advapi32.LsaOpenPolicy(ref systemName, ref ObjectAttributes, access, out policyHandle);
uint resultPolicy = Advapi32.LsaOpenPolicy(ref systemName, ref objectAttributes, access, out policyHandle);
winErrorCode = Advapi32.LsaNtStatusToWinError(resultPolicy);
if (winErrorCode != 0)
@ -324,6 +334,7 @@ namespace winsw
}
// enum all policies
[Flags]
enum LSA_AccessPolicy : long
{
POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L,
@ -346,6 +357,7 @@ namespace winsw
/// <summary>
/// Required to connect to the service control manager.
/// </summary>
SC_MANAGER_CONNECT = 0x00001,
/// <summary>
@ -514,8 +526,8 @@ namespace winsw
public SC_ACTION(SC_ACTION_TYPE type, TimeSpan delay)
{
this.Type = type;
this.Delay = (uint)delay.TotalMilliseconds;
Type = type;
Delay = (uint)delay.TotalMilliseconds;
}
}

View File

@ -1,17 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Text;
using System.IO;
using System.Net;
using WMI;
using System.Xml;
using System.Threading;
using Microsoft.Win32;
namespace winsw
{

View File

@ -1,6 +1,6 @@
using System;
using System.Reflection;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
@ -85,11 +85,11 @@ namespace DynamicProxy
/// </summary>
public class ProxyFactory
{
private static ProxyFactory instance;
private static Object lockObj = new Object();
private static ProxyFactory _instance;
private static readonly Object LockObj = new Object();
private Hashtable typeMap = Hashtable.Synchronized(new Hashtable());
private static readonly Hashtable opCodeTypeMapper = new Hashtable();
private readonly Hashtable _typeMap = Hashtable.Synchronized(new Hashtable());
private static readonly Hashtable OpCodeTypeMapper = new Hashtable();
private const string PROXY_SUFFIX = "Proxy";
private const string ASSEMBLY_NAME = "ProxyAssembly";
@ -100,14 +100,14 @@ namespace DynamicProxy
// return types, used in the Emit process.
static ProxyFactory()
{
opCodeTypeMapper.Add(typeof(System.Boolean), OpCodes.Ldind_I1);
opCodeTypeMapper.Add(typeof(System.Int16), OpCodes.Ldind_I2);
opCodeTypeMapper.Add(typeof(System.Int32), OpCodes.Ldind_I4);
opCodeTypeMapper.Add(typeof(System.Int64), OpCodes.Ldind_I8);
opCodeTypeMapper.Add(typeof(System.Double), OpCodes.Ldind_R8);
opCodeTypeMapper.Add(typeof(System.Single), OpCodes.Ldind_R4);
opCodeTypeMapper.Add(typeof(System.UInt16), OpCodes.Ldind_U2);
opCodeTypeMapper.Add(typeof(System.UInt32), OpCodes.Ldind_U4);
OpCodeTypeMapper.Add(typeof(Boolean), OpCodes.Ldind_I1);
OpCodeTypeMapper.Add(typeof(Int16), OpCodes.Ldind_I2);
OpCodeTypeMapper.Add(typeof(Int32), OpCodes.Ldind_I4);
OpCodeTypeMapper.Add(typeof(Int64), OpCodes.Ldind_I8);
OpCodeTypeMapper.Add(typeof(Double), OpCodes.Ldind_R8);
OpCodeTypeMapper.Add(typeof(Single), OpCodes.Ldind_R4);
OpCodeTypeMapper.Add(typeof(UInt16), OpCodes.Ldind_U2);
OpCodeTypeMapper.Add(typeof(UInt32), OpCodes.Ldind_U4);
}
private ProxyFactory()
@ -116,21 +116,21 @@ namespace DynamicProxy
public static ProxyFactory GetInstance()
{
if (instance == null)
if (_instance == null)
{
CreateInstance();
}
return instance;
return _instance;
}
private static void CreateInstance()
{
lock (lockObj)
lock (LockObj)
{
if (instance == null)
if (_instance == null)
{
instance = new ProxyFactory();
_instance = new ProxyFactory();
}
}
}
@ -138,7 +138,7 @@ namespace DynamicProxy
public Object Create(IProxyInvocationHandler handler, Type objType, bool isObjInterface)
{
string typeName = objType.FullName + PROXY_SUFFIX;
Type type = (Type)typeMap[typeName];
Type type = (Type)_typeMap[typeName];
// check to see if the type was in the cache. If the type was not cached, then
// create a new instance of the dynamic type and add it to the cache.
@ -153,7 +153,7 @@ namespace DynamicProxy
type = CreateType(handler, objType.GetInterfaces(), typeName);
}
typeMap.Add(typeName, type);
_typeMap.Add(typeName, type);
}
// return a new instance of the type.
@ -171,7 +171,7 @@ namespace DynamicProxy
if (handler != null && interfaces != null)
{
Type objType = typeof(System.Object);
Type objType = typeof(Object);
Type handlerType = typeof(IProxyInvocationHandler);
AppDomain domain = Thread.GetDomain();
@ -316,7 +316,7 @@ namespace DynamicProxy
} else if ( !methodInfo.ReturnType.IsPrimitive ) {
methodIL.Emit( OpCodes.Ldobj, methodInfo.ReturnType );
} else {
methodIL.Emit( (OpCode) opCodeTypeMapper[ methodInfo.ReturnType ] );
methodIL.Emit( (OpCode) OpCodeTypeMapper[ methodInfo.ReturnType ] );
}
}
} else {

View File

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace winsw

View File

@ -1,9 +1,10 @@
using System.IO;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace winsw
{
// ReSharper disable once InconsistentNaming
public interface EventLogger
{
void LogEvent(string message);
@ -15,24 +16,13 @@ namespace winsw
/// </summary>
public abstract class LogHandler
{
private EventLogger eventLogger;
// ReSharper disable once InconsistentNaming
public abstract void log(Stream outputStream, Stream errorStream);
/// <summary>
/// Error and information about logging should be reported here.
/// </summary>
public EventLogger EventLogger
{
set
{
this.eventLogger = value;
}
get
{
return this.eventLogger;
}
}
public EventLogger EventLogger { set; get; }
/// <summary>
/// Convenience method to copy stuff from StreamReader to StreamWriter
@ -73,59 +63,32 @@ namespace winsw
/// </summary>
public abstract class AbstractFileLogAppender : LogHandler
{
private string baseLogFileName;
protected string BaseLogFileName { private set; get; }
public AbstractFileLogAppender(string logDirectory, string baseName)
{
this.baseLogFileName = Path.Combine(logDirectory, baseName);
BaseLogFileName = Path.Combine(logDirectory, baseName);
}
protected string BaseLogFileName
{
get
{
return this.baseLogFileName;
}
}
}
public abstract class SimpleLogAppender : AbstractFileLogAppender
{
private FileMode fileMode;
private string outputLogFileName;
private string errorLogFileName;
public FileMode FileMode { private set; get; }
public string OutputLogFileName { private set; get; }
public string ErrorLogFileName { private set; get; }
public SimpleLogAppender(string logDirectory, string baseName, FileMode fileMode)
: base(logDirectory, baseName)
{
this.fileMode = fileMode;
this.outputLogFileName = BaseLogFileName + ".out.log";
this.errorLogFileName = BaseLogFileName + ".err.log";
}
public string OutputLogFileName
{
get
{
return this.outputLogFileName;
}
}
public string ErrorLogFileName
{
get
{
return this.errorLogFileName;
}
FileMode = fileMode;
OutputLogFileName = BaseLogFileName + ".out.log";
ErrorLogFileName = BaseLogFileName + ".err.log";
}
public override void log(Stream outputStream, Stream errorStream)
{
new Thread(delegate() { CopyStream(outputStream, new FileStream(outputLogFileName, fileMode)); }).Start();
new Thread(delegate() { CopyStream(errorStream, new FileStream(errorLogFileName, fileMode)); }).Start();
new Thread(delegate() { CopyStream(outputStream, new FileStream(OutputLogFileName, FileMode)); }).Start();
new Thread(delegate() { CopyStream(errorStream, new FileStream(ErrorLogFileName, FileMode)); }).Start();
}
}
@ -159,31 +122,14 @@ namespace winsw
public class TimeBasedRollingLogAppender : AbstractFileLogAppender
{
private string pattern;
private int period;
public string Pattern
{
get
{
return pattern;
}
}
public int Period
{
get
{
return period;
}
}
public string Pattern { get; private set; }
public int Period { get; private set; }
public TimeBasedRollingLogAppender(string logDirectory, string baseName, string pattern, int period)
: base(logDirectory, baseName)
{
this.pattern = pattern;
this.period = period;
Pattern = pattern;
Period = period;
}
public override void log(Stream outputStream, Stream errorStream)
@ -197,7 +143,7 @@ namespace winsw
/// </summary>
private void CopyStreamWithDateRotation(Stream data, string ext)
{
PeriodicRollingCalendar periodicRollingCalendar = new PeriodicRollingCalendar(pattern, period);
PeriodicRollingCalendar periodicRollingCalendar = new PeriodicRollingCalendar(Pattern, Period);
periodicRollingCalendar.init();
byte[] buf = new byte[1024];
@ -254,35 +200,24 @@ namespace winsw
public class SizeBasedRollingLogAppender : AbstractFileLogAppender
{
// ReSharper disable once InconsistentNaming
public static int BYTES_PER_KB = 1024;
// ReSharper disable once InconsistentNaming
public static int BYTES_PER_MB = 1024 * BYTES_PER_KB;
// ReSharper disable once InconsistentNaming
public static int DEFAULT_SIZE_THRESHOLD = 10 * BYTES_PER_MB; // rotate every 10MB.
// ReSharper disable once InconsistentNaming
public static int DEFAULT_FILES_TO_KEEP = 8;
private int sizeThreshold;
private int filesToKeep;
public int SizeTheshold { private set; get; }
public int SizeTheshold
{
get
{
return sizeThreshold;
}
}
public int FilesToKeep
{
get
{
return filesToKeep;
}
}
public int FilesToKeep { private set; get; }
public SizeBasedRollingLogAppender(string logDirectory, string baseName, int sizeThreshold, int filesToKeep)
: base(logDirectory, baseName)
{
this.sizeThreshold = sizeThreshold;
this.filesToKeep = filesToKeep;
SizeTheshold = sizeThreshold;
FilesToKeep = filesToKeep;
}
public SizeBasedRollingLogAppender(string logDirectory, string baseName)
@ -307,7 +242,7 @@ namespace winsw
{
int len = data.Read(buf, 0, buf.Length);
if (len == 0) break; // EOF
if (sz + len < sizeThreshold)
if (sz + len < SizeTheshold)
{// typical case. write the whole thing into the current file
w.Write(buf, 0, len);
sz += len;
@ -319,7 +254,7 @@ namespace winsw
for (int i = 0; i < len; i++)
{
if (buf[i] != 0x0A) continue;
if (sz + i < sizeThreshold) continue;
if (sz + i < SizeTheshold) continue;
// at the line boundary and exceeded the rotation unit.
// time to rotate.
@ -329,7 +264,7 @@ namespace winsw
try
{
for (int j = filesToKeep; j >= 1; j--)
for (int j = FilesToKeep; j >= 1; j--)
{
string dst = BaseLogFileName + "." + (j - 1) + ext;
string src = BaseLogFileName + "." + (j - 2) + ext;

71
Main.cs
View File

@ -1,18 +1,15 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Management;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Text;
using System.IO;
using System.Net;
using WMI;
using System.Xml;
using System.Threading;
using Microsoft.Win32;
using System.Management;
using WMI;
using ServiceType = WMI.ServiceType;
namespace winsw
{
@ -20,26 +17,26 @@ namespace winsw
{
private SERVICE_STATUS wrapperServiceStatus;
private Process process = new Process();
private ServiceDescriptor descriptor;
private Dictionary<string, string> envs;
private readonly Process process = new Process();
private readonly ServiceDescriptor descriptor;
private Dictionary<string, string> _envs;
/// <summary>
/// Indicates to the watch dog thread that we are going to terminate the process,
/// so don't try to kill us when the child exits.
/// </summary>
private bool orderlyShutdown;
private bool systemShuttingdown;
private bool _orderlyShutdown;
private bool _systemShuttingdown;
public WrapperService()
{
this.descriptor = new ServiceDescriptor();
this.ServiceName = descriptor.Id;
this.CanShutdown = true;
this.CanStop = true;
this.CanPauseAndContinue = false;
this.AutoLog = true;
this.systemShuttingdown = false;
descriptor = new ServiceDescriptor();
ServiceName = descriptor.Id;
CanShutdown = true;
CanStop = true;
CanPauseAndContinue = false;
AutoLog = true;
_systemShuttingdown = false;
}
/// <summary>
@ -132,7 +129,7 @@ namespace winsw
public void LogEvent(String message)
{
if (systemShuttingdown)
if (_systemShuttingdown)
{
/* NOP - cannot call EventLog because of shutdown. */
}
@ -151,7 +148,7 @@ namespace winsw
public void LogEvent(String message, EventLogEntryType type)
{
if (systemShuttingdown)
if (_systemShuttingdown)
{
/* NOP - cannot call EventLog because of shutdown. */
}
@ -190,10 +187,10 @@ namespace winsw
protected override void OnStart(string[] _)
{
envs = descriptor.EnvironmentVariables;
foreach (string key in envs.Keys)
_envs = descriptor.EnvironmentVariables;
foreach (string key in _envs.Keys)
{
LogEvent("envar " + key + '=' + envs[key]);
LogEvent("envar " + key + '=' + _envs[key]);
}
HandleFileCopies();
@ -242,7 +239,7 @@ namespace winsw
try
{
this.systemShuttingdown = true;
_systemShuttingdown = true;
StopIt();
}
catch (Exception ex)
@ -273,7 +270,7 @@ namespace winsw
string stoparguments = descriptor.Stoparguments;
LogEvent("Stopping " + descriptor.Id);
WriteEvent("Stopping " + descriptor.Id);
orderlyShutdown = true;
_orderlyShutdown = true;
if (stoparguments == null)
{
@ -309,7 +306,7 @@ namespace winsw
SignalShutdownComplete();
}
if (systemShuttingdown && descriptor.BeepOnShutdown)
if (_systemShuttingdown && descriptor.BeepOnShutdown)
{
Console.Beep();
}
@ -386,7 +383,7 @@ namespace winsw
}
}
private void WaitForProcessToExit(Process process)
private void WaitForProcessToExit(Process processoWait)
{
SignalShutdownPending();
@ -394,7 +391,7 @@ namespace winsw
{
// WriteEvent("WaitForProcessToExit [start]");
while (!process.WaitForExit(descriptor.SleepTime.Milliseconds))
while (!processoWait.WaitForExit(descriptor.SleepTime.Milliseconds))
{
SignalShutdownPending();
// WriteEvent("WaitForProcessToExit [repeat]");
@ -410,7 +407,7 @@ namespace winsw
private void SignalShutdownPending()
{
IntPtr handle = this.ServiceHandle;
IntPtr handle = ServiceHandle;
wrapperServiceStatus.checkPoint++;
wrapperServiceStatus.waitHint = descriptor.WaitHint.Milliseconds;
// WriteEvent("SignalShutdownPending " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint);
@ -420,7 +417,7 @@ namespace winsw
private void SignalShutdownComplete()
{
IntPtr handle = this.ServiceHandle;
IntPtr handle = ServiceHandle;
wrapperServiceStatus.checkPoint++;
// WriteEvent("SignalShutdownComplete " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint);
wrapperServiceStatus.currentState = (int)State.SERVICE_STOPPED;
@ -439,8 +436,8 @@ namespace winsw
ps.RedirectStandardOutput = true;
ps.RedirectStandardError = true;
foreach (string key in envs.Keys)
System.Environment.SetEnvironmentVariable(key, envs[key]);
foreach (string key in _envs.Keys)
Environment.SetEnvironmentVariable(key, _envs[key]);
// ps.EnvironmentVariables[key] = envs[key]; // bugged (lower cases all variable names due to StringDictionary being used, see http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=326163)
process.Start();
@ -451,14 +448,14 @@ namespace winsw
process.PriorityClass = priority;
// monitor the completion of the process
StartThread(delegate()
StartThread(delegate
{
string msg = process.Id + " - " + process.StartInfo.FileName + " " + process.StartInfo.Arguments;
process.WaitForExit();
try
{
if (orderlyShutdown)
if (_orderlyShutdown)
{
LogEvent("Child process [" + msg + "] terminated with " + process.ExitCode, EventLogEntryType.Information);
}
@ -585,7 +582,7 @@ namespace winsw
d.Id,
d.Caption,
"\"" + d.ExecutablePath + "\"",
WMI.ServiceType.OwnProcess,
ServiceType.OwnProcess,
ErrorControl.UserNotified,
StartMode.Automatic,
d.Interactive,
@ -688,7 +685,7 @@ namespace winsw
}
return;
}
ServiceBase.Run(new WrapperService());
Run(new WrapperService());
}
private static string ReadPassword()

View File

@ -1,5 +1,6 @@
using System;
using System.Data;
// ReSharper disable InconsistentNaming
namespace winsw
{
@ -8,23 +9,22 @@ namespace winsw
**/
public class PeriodicRollingCalendar
{
private PeriodicityType _periodicityType;
private string _format;
private long _period;
private readonly string _format;
private readonly long _period;
private DateTime _currentRoll;
private DateTime _nextRoll;
public PeriodicRollingCalendar(string format, long period)
{
this._format = format;
this._period = period;
this._currentRoll = DateTime.Now;
_format = format;
_period = period;
_currentRoll = DateTime.Now;
}
public void init()
{
this._periodicityType = determinePeriodicityType();
this._nextRoll = nextTriggeringTime(this._currentRoll, this._period);
periodicityType = determinePeriodicityType();
_nextRoll = nextTriggeringTime(_currentRoll, _period);
}
public enum PeriodicityType
@ -32,7 +32,7 @@ namespace winsw
ERRONEOUS, TOP_OF_MILLISECOND, TOP_OF_SECOND, TOP_OF_MINUTE, TOP_OF_HOUR, TOP_OF_DAY
}
private static PeriodicityType[] VALID_ORDERED_LIST = new PeriodicityType[] {
private static readonly PeriodicityType[] VALID_ORDERED_LIST = {
PeriodicityType.TOP_OF_MILLISECOND, PeriodicityType.TOP_OF_SECOND, PeriodicityType.TOP_OF_MINUTE, PeriodicityType.TOP_OF_HOUR, PeriodicityType.TOP_OF_DAY
};
@ -60,7 +60,7 @@ namespace winsw
private DateTime nextTriggeringTime(DateTime input, long increment)
{
DateTime output;
switch (_periodicityType)
switch (periodicityType)
{
case PeriodicityType.TOP_OF_MILLISECOND:
output = new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, input.Second, input.Millisecond);
@ -83,27 +83,21 @@ namespace winsw
output = output.AddDays(increment);
return output;
default:
throw new Exception("invalid periodicity type: " + _periodicityType);
throw new Exception("invalid periodicity type: " + periodicityType);
}
}
public PeriodicityType periodicityType
{
set
{
this._periodicityType = value;
}
}
public PeriodicityType periodicityType { get; set; }
public Boolean shouldRoll
{
get
{
DateTime now = DateTime.Now;
if (now > this._nextRoll)
if (now > _nextRoll)
{
this._currentRoll = now;
this._nextRoll = nextTriggeringTime(now, this._period);
_currentRoll = now;
_nextRoll = nextTriggeringTime(now, _period);
return true;
}
return false;
@ -114,7 +108,7 @@ namespace winsw
{
get
{
return this._currentRoll.ToString(this._format);
return _currentRoll.ToString(_format);
}
}

View File

@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Windows Service Wrapper")]

View File

@ -1,18 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Text;
using System.IO;
using System.Net;
using WMI;
using System.Reflection;
using System.Xml;
using System.Threading;
using Microsoft.Win32;
namespace winsw
{
@ -21,6 +13,7 @@ namespace winsw
/// </summary>
public class ServiceDescriptor
{
// ReSharper disable once InconsistentNaming
protected readonly XmlDocument dom = new XmlDocument();
/// <summary>
@ -132,7 +125,7 @@ namespace winsw
private TimeSpan ParseTimeSpan(string v)
{
v = v.Trim();
foreach (var s in SUFFIX)
foreach (var s in Suffix)
{
if (v.EndsWith(s.Key))
{
@ -142,7 +135,7 @@ namespace winsw
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> {
{ "ms", 1 },
{ "sec", 1000L },
{ "secs", 1000L },
@ -362,7 +355,7 @@ namespace winsw
{
get
{
System.Collections.ArrayList serviceDependencies = new System.Collections.ArrayList();
ArrayList serviceDependencies = new ArrayList();
foreach (XmlNode depend in dom.SelectNodes("//depend"))
{
@ -548,13 +541,16 @@ namespace winsw
}
}
// ReSharper disable once InconsistentNaming
protected string serviceAccountDomain
{
get{
get
{
return GetServiceAccountPart("domain");
}
}
// ReSharper disable once InconsistentNaming
protected string serviceAccountName
{
get
@ -587,7 +583,7 @@ namespace winsw
{
if (AllowServiceLogon != null)
{
bool parsedvalue = false;
bool parsedvalue;
if (Boolean.TryParse(AllowServiceLogon, out parsedvalue))
{
return parsedvalue;

View File

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
namespace winsw
{

View File

@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following

View File

@ -1,17 +1,15 @@
using NUnit.Framework;
using winsw;
using System;
using System.Diagnostics;
using System.Xml;
using NUnit.Framework;
using winsw;
namespace winswTests
{
using System;
[TestFixture]
public class ServiceDescriptorTests
{
private ServiceDescriptor extendedServiceDescriptor;
private ServiceDescriptor _extendedServiceDescriptor;
private const string ExpectedWorkingDirectory = @"Z:\Path\SubPath";
private const string Username = "User";
@ -22,7 +20,7 @@ namespace winswTests
[SetUp]
public void SetUp()
{
const string SeedXml = "<service>"
const string seedXml = "<service>"
+ "<id>service.exe</id>"
+ "<name>Service</name>"
+ "<description>The service.</description>"
@ -40,34 +38,34 @@ namespace winswTests
+ "</workingdirectory>"
+ @"<logpath>C:\logs</logpath>"
+ "</service>";
extendedServiceDescriptor = ServiceDescriptor.FromXML(SeedXml);
_extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
}
[Test]
public void VerifyWorkingDirectory()
{
System.Diagnostics.Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + extendedServiceDescriptor.WorkingDirectory);
Assert.That(extendedServiceDescriptor.WorkingDirectory, Is.EqualTo(ExpectedWorkingDirectory));
Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory);
Assert.That(_extendedServiceDescriptor.WorkingDirectory, Is.EqualTo(ExpectedWorkingDirectory));
}
[Test]
public void VerifyServiceLogonRight()
{
Assert.That(extendedServiceDescriptor.AllowServiceAcountLogonRight, Is.EqualTo(true));
Assert.That(_extendedServiceDescriptor.AllowServiceAcountLogonRight, Is.EqualTo(true));
}
[Test]
public void VerifyUsername()
{
System.Diagnostics.Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + extendedServiceDescriptor.WorkingDirectory);
Assert.That(extendedServiceDescriptor.ServiceAccountUser, Is.EqualTo(Domain + "\\" + Username));
Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory);
Assert.That(_extendedServiceDescriptor.ServiceAccountUser, Is.EqualTo(Domain + "\\" + Username));
}
[Test]
public void VerifyPassword()
{
System.Diagnostics.Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + extendedServiceDescriptor.WorkingDirectory);
Assert.That(extendedServiceDescriptor.ServiceAccountPassword, Is.EqualTo(Password));
Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory);
Assert.That(_extendedServiceDescriptor.ServiceAccountPassword, Is.EqualTo(Password));
}
[Test]
@ -86,16 +84,16 @@ namespace winswTests
[Test]
public void StopParentProcessFirstIsFalseByDefault()
{
Assert.False(extendedServiceDescriptor.StopParentProcessFirst);
Assert.False(_extendedServiceDescriptor.StopParentProcessFirst);
}
[Test]
public void CanParseStopParentProcessFirst()
{
const string SeedXml = "<service>"
const string seedXml = "<service>"
+ "<stopparentprocessfirst>true</stopparentprocessfirst>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.True(serviceDescriptor.StopParentProcessFirst);
}
@ -103,10 +101,10 @@ namespace winswTests
[Test]
public void CanParseStopTimeout()
{
const string SeedXml = "<service>"
const string seedXml = "<service>"
+ "<stoptimeout>60sec</stoptimeout>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromSeconds(60)));
}
@ -114,10 +112,10 @@ namespace winswTests
[Test]
public void CanParseStopTimeoutFromMinutes()
{
const string SeedXml = "<service>"
const string seedXml = "<service>"
+ "<stoptimeout>10min</stoptimeout>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromMinutes(10)));
}
@ -125,7 +123,7 @@ namespace winswTests
[Test]
public void LogModeRollBySize()
{
const string SeedXml = "<service>"
const string seedXml = "<service>"
+ "<logpath>c:\\</logpath>"
+ "<log mode=\"roll-by-size\">"
+ "<sizeThreshold>112</sizeThreshold>"
@ -133,7 +131,7 @@ namespace winswTests
+ "</log>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
serviceDescriptor.BaseName = "service";
var logHandler = serviceDescriptor.LogHandler as SizeBasedRollingLogAppender;
@ -145,7 +143,7 @@ namespace winswTests
[Test]
public void LogModeRollByTime()
{
const string SeedXml = "<service>"
const string seedXml = "<service>"
+ "<logpath>c:\\</logpath>"
+ "<log mode=\"roll-by-time\">"
+ "<period>7</period>"
@ -153,7 +151,7 @@ namespace winswTests
+ "</log>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
serviceDescriptor.BaseName = "service";
var logHandler = serviceDescriptor.LogHandler as TimeBasedRollingLogAppender;
@ -165,7 +163,7 @@ namespace winswTests
[Test]
public void VerifyServiceLogonRightGraceful()
{
const string SeedXml="<service>"
const string seedXml="<service>"
+ "<serviceaccount>"
+ "<domain>" + Domain + "</domain>"
+ "<user>" + Username + "</user>"
@ -173,20 +171,20 @@ namespace winswTests
+ "<allowservicelogon>true1</allowservicelogon>"
+ "</serviceaccount>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(serviceDescriptor.AllowServiceAcountLogonRight, Is.EqualTo(false));
}
[Test]
public void VerifyServiceLogonRightOmitted()
{
const string SeedXml = "<service>"
const string seedXml = "<service>"
+ "<serviceaccount>"
+ "<domain>" + Domain + "</domain>"
+ "<user>" + Username + "</user>"
+ "<password>" + Password + "</password>"
+ "</serviceaccount>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(serviceDescriptor.AllowServiceAcountLogonRight, Is.EqualTo(false));
}
}

42
Wmi.cs
View File

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Management;
using System.Reflection;
using DynamicProxy;
namespace WMI
@ -65,7 +63,7 @@ namespace WMI
public class WmiClassName : Attribute
{
public readonly string Name;
public WmiClassName(string name) { this.Name = name; }
public WmiClassName(string name) { Name = name; }
}
/// <summary>
@ -107,7 +105,7 @@ namespace WMI
scope.Connect();
}
private static string capitalize(string s)
private static string Capitalize(string s)
{
return char.ToUpper(s[0]) + s.Substring(1);
}
@ -126,9 +124,9 @@ namespace WMI
class InstanceHandler : BaseHandler, IWmiObject
{
private readonly ManagementObject mo;
private readonly ManagementObject _mo;
public InstanceHandler(ManagementObject o) { this.mo = o; }
public InstanceHandler(ManagementObject o) { _mo = o; }
public override object Invoke(object proxy, MethodInfo method, object[] args)
{
@ -140,37 +138,37 @@ namespace WMI
// TODO: proper property support
if (method.Name.StartsWith("set_"))
{
mo[method.Name.Substring(4)] = args[0];
_mo[method.Name.Substring(4)] = args[0];
return null;
}
if (method.Name.StartsWith("get_"))
{
return mo[method.Name.Substring(4)];
return _mo[method.Name.Substring(4)];
}
// method invocations
ParameterInfo[] methodArgs = method.GetParameters();
ManagementBaseObject wmiArgs = mo.GetMethodParameters(method.Name);
ManagementBaseObject wmiArgs = _mo.GetMethodParameters(method.Name);
for (int i = 0; i < args.Length; i++)
wmiArgs[capitalize(methodArgs[i].Name)] = args[i];
wmiArgs[Capitalize(methodArgs[i].Name)] = args[i];
CheckError(mo.InvokeMethod(method.Name, wmiArgs, null));
CheckError(_mo.InvokeMethod(method.Name, wmiArgs, null));
return null;
}
public void Commit()
{
mo.Put();
_mo.Put();
}
}
class ClassHandler : BaseHandler
{
private readonly ManagementClass mc;
private readonly string wmiClass;
private readonly ManagementClass _mc;
private readonly string _wmiClass;
public ClassHandler(ManagementClass mc, string wmiClass) { this.mc = mc; this.wmiClass = wmiClass; }
public ClassHandler(ManagementClass mc, string wmiClass) { _mc = mc; _wmiClass = wmiClass; }
public override object Invoke(object proxy, MethodInfo method, object[] args)
{
@ -179,14 +177,14 @@ namespace WMI
if (method.Name.StartsWith("Select"))
{
// select method to find instances
string query = "SELECT * FROM " + wmiClass + " WHERE ";
string query = "SELECT * FROM " + _wmiClass + " WHERE ";
for (int i = 0; i < args.Length; i++)
{
if (i != 0) query += " AND ";
query += ' ' + capitalize(methodArgs[i].Name) + " = '" + args[i] + "'";
query += ' ' + Capitalize(methodArgs[i].Name) + " = '" + args[i] + "'";
}
ManagementObjectSearcher searcher = new ManagementObjectSearcher(mc.Scope, new ObjectQuery(query));
ManagementObjectSearcher searcher = new ManagementObjectSearcher(_mc.Scope, new ObjectQuery(query));
ManagementObjectCollection results = searcher.Get();
// TODO: support collections
foreach (ManagementObject manObject in results)
@ -194,11 +192,11 @@ namespace WMI
return null;
}
ManagementBaseObject wmiArgs = mc.GetMethodParameters(method.Name);
ManagementBaseObject wmiArgs = _mc.GetMethodParameters(method.Name);
for (int i = 0; i < args.Length; i++)
wmiArgs[capitalize(methodArgs[i].Name)] = args[i];
wmiArgs[Capitalize(methodArgs[i].Name)] = args[i];
CheckError(mc.InvokeMethod(method.Name, wmiArgs, null));
CheckError(_mc.InvokeMethod(method.Name, wmiArgs, null));
return null;
}
}