mirror of https://github.com/winsw/winsw
Refactoring: cleanup the codestyle, convert vars to properties, etc.
Signed-off-by: Oleg Nenashev <o.v.nenashev@gmail.com>pull/75/head
parent
0105fe5214
commit
6fcebfa0e2
96
Advapi32.cs
96
Advapi32.cs
|
@ -1,19 +1,21 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
namespace winsw
|
namespace winsw
|
||||||
{
|
{
|
||||||
class ServiceManager : IDisposable
|
class ServiceManager : IDisposable
|
||||||
{
|
{
|
||||||
private IntPtr Handle;
|
private IntPtr _handle;
|
||||||
|
|
||||||
public ServiceManager()
|
public ServiceManager()
|
||||||
{
|
{
|
||||||
Handle = Advapi32.OpenSCManager(null, null, (uint)SCM_ACCESS.SC_MANAGER_ALL_ACCESS);
|
_handle = Advapi32.OpenSCManager(null, null, (uint)SCM_ACCESS.SC_MANAGER_ALL_ACCESS);
|
||||||
if (Handle == IntPtr.Zero)
|
if (_handle == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
throw new Exception(String.Format("Error connecting to Service Control Manager. Error provided was: 0x{0:X}", Marshal.GetLastWin32Error()));
|
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)
|
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)
|
if (svcHandle == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
throw new Exception(String.Format("Error opening service for modifying. Error returned was: 0x{0:X}", Marshal.GetLastWin32Error()));
|
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()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (Handle != IntPtr.Zero)
|
if (_handle != IntPtr.Zero)
|
||||||
Advapi32.CloseServiceHandle(Handle);
|
Advapi32.CloseServiceHandle(_handle);
|
||||||
Handle = IntPtr.Zero;
|
_handle = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,10 +50,14 @@ namespace winsw
|
||||||
|
|
||||||
public void ChangeConfig(TimeSpan failureResetPeriod, List<SC_ACTION> actions)
|
public void ChangeConfig(TimeSpan failureResetPeriod, List<SC_ACTION> actions)
|
||||||
{
|
{
|
||||||
SERVICE_FAILURE_ACTIONS sfa = new SERVICE_FAILURE_ACTIONS();
|
SERVICE_FAILURE_ACTIONS sfa = new SERVICE_FAILURE_ACTIONS
|
||||||
sfa.dwResetPeriod = (int)failureResetPeriod.TotalSeconds;
|
{
|
||||||
sfa.lpRebootMsg = ""; // delete message
|
dwResetPeriod = (int) failureResetPeriod.TotalSeconds,
|
||||||
sfa.lpCommand = ""; // delete the command to run
|
lpRebootMsg = "",
|
||||||
|
lpCommand = ""
|
||||||
|
};
|
||||||
|
// delete message
|
||||||
|
// delete the command to run
|
||||||
|
|
||||||
int len = Marshal.SizeOf(typeof(SC_ACTION));
|
int len = Marshal.SizeOf(typeof(SC_ACTION));
|
||||||
|
|
||||||
|
@ -83,15 +89,15 @@ namespace winsw
|
||||||
|
|
||||||
static class LogonAsAService
|
static class LogonAsAService
|
||||||
{
|
{
|
||||||
public static void AddLogonAsAServiceRight(string Username)
|
public static void AddLogonAsAServiceRight(string username)
|
||||||
{
|
{
|
||||||
//Needs to be at least XP or 2003 server
|
//Needs to be at least XP or 2003 server
|
||||||
//https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx
|
//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)
|
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);
|
//Trace.WriteLine("Username for Logon as A Service: " + newuser);
|
||||||
long rightexitcode = SetRight(newuser, PrivlegeRights.SeServiceLogonRight.ToString());
|
long rightexitcode = SetRight(newuser, PrivlegeRights.SeServiceLogonRight.ToString());
|
||||||
if (rightexitcode != 0)
|
if (rightexitcode != 0)
|
||||||
|
@ -108,17 +114,19 @@ namespace winsw
|
||||||
|
|
||||||
private static string GetDomain(string s)
|
private static string GetDomain(string s)
|
||||||
{
|
{
|
||||||
int stop = s.IndexOf("\\");
|
int stop = s.IndexOf("\\", StringComparison.Ordinal);
|
||||||
if (stop >= 0)
|
if (stop >= 0)
|
||||||
return s.Substring(0, stop);
|
return s.Substring(0, stop);
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetLogin(string s)
|
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;
|
return (stop > -1) ? s.Substring(stop + 1, s.Length - stop - 1) : s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetLocalAccountIfLocalAccount(string username)
|
private static string GetLocalAccountIfLocalAccount(string username)
|
||||||
{
|
{
|
||||||
var machinename = Environment.MachineName;
|
var machinename = Environment.MachineName;
|
||||||
|
@ -174,34 +182,36 @@ namespace winsw
|
||||||
//initialize an empty unicode-string
|
//initialize an empty unicode-string
|
||||||
LSA_UNICODE_STRING systemName = new LSA_UNICODE_STRING();
|
LSA_UNICODE_STRING systemName = new LSA_UNICODE_STRING();
|
||||||
//combine all policies
|
//combine all policies
|
||||||
int access = (int)(
|
const int access = (int)(
|
||||||
LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN |
|
LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN |
|
||||||
LSA_AccessPolicy.POLICY_CREATE_ACCOUNT |
|
LSA_AccessPolicy.POLICY_CREATE_ACCOUNT |
|
||||||
LSA_AccessPolicy.POLICY_CREATE_PRIVILEGE |
|
LSA_AccessPolicy.POLICY_CREATE_PRIVILEGE |
|
||||||
LSA_AccessPolicy.POLICY_CREATE_SECRET |
|
LSA_AccessPolicy.POLICY_CREATE_SECRET |
|
||||||
LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION |
|
LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION |
|
||||||
LSA_AccessPolicy.POLICY_LOOKUP_NAMES |
|
LSA_AccessPolicy.POLICY_LOOKUP_NAMES |
|
||||||
LSA_AccessPolicy.POLICY_NOTIFICATION |
|
LSA_AccessPolicy.POLICY_NOTIFICATION |
|
||||||
LSA_AccessPolicy.POLICY_SERVER_ADMIN |
|
LSA_AccessPolicy.POLICY_SERVER_ADMIN |
|
||||||
LSA_AccessPolicy.POLICY_SET_AUDIT_REQUIREMENTS |
|
LSA_AccessPolicy.POLICY_SET_AUDIT_REQUIREMENTS |
|
||||||
LSA_AccessPolicy.POLICY_SET_DEFAULT_QUOTA_LIMITS |
|
LSA_AccessPolicy.POLICY_SET_DEFAULT_QUOTA_LIMITS |
|
||||||
LSA_AccessPolicy.POLICY_TRUST_ADMIN |
|
LSA_AccessPolicy.POLICY_TRUST_ADMIN |
|
||||||
LSA_AccessPolicy.POLICY_VIEW_AUDIT_INFORMATION |
|
LSA_AccessPolicy.POLICY_VIEW_AUDIT_INFORMATION |
|
||||||
LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION
|
LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION
|
||||||
);
|
);
|
||||||
//initialize a pointer for the policy handle
|
//initialize a pointer for the policy handle
|
||||||
IntPtr policyHandle = IntPtr.Zero;
|
IntPtr policyHandle = IntPtr.Zero;
|
||||||
|
|
||||||
//these attributes are not used, but LsaOpenPolicy wants them to exists
|
//these attributes are not used, but LsaOpenPolicy wants them to exists
|
||||||
LSA_OBJECT_ATTRIBUTES ObjectAttributes = new LSA_OBJECT_ATTRIBUTES();
|
LSA_OBJECT_ATTRIBUTES objectAttributes = new LSA_OBJECT_ATTRIBUTES
|
||||||
ObjectAttributes.Length = 0;
|
{
|
||||||
ObjectAttributes.RootDirectory = IntPtr.Zero;
|
Length = 0,
|
||||||
ObjectAttributes.Attributes = 0;
|
RootDirectory = IntPtr.Zero,
|
||||||
ObjectAttributes.SecurityDescriptor = IntPtr.Zero;
|
Attributes = 0,
|
||||||
ObjectAttributes.SecurityQualityOfService = IntPtr.Zero;
|
SecurityDescriptor = IntPtr.Zero,
|
||||||
|
SecurityQualityOfService = IntPtr.Zero
|
||||||
|
};
|
||||||
|
|
||||||
//get a policy handle
|
//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);
|
winErrorCode = Advapi32.LsaNtStatusToWinError(resultPolicy);
|
||||||
|
|
||||||
if (winErrorCode != 0)
|
if (winErrorCode != 0)
|
||||||
|
@ -324,6 +334,7 @@ namespace winsw
|
||||||
}
|
}
|
||||||
|
|
||||||
// enum all policies
|
// enum all policies
|
||||||
|
[Flags]
|
||||||
enum LSA_AccessPolicy : long
|
enum LSA_AccessPolicy : long
|
||||||
{
|
{
|
||||||
POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L,
|
POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L,
|
||||||
|
@ -346,6 +357,7 @@ namespace winsw
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required to connect to the service control manager.
|
/// Required to connect to the service control manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
SC_MANAGER_CONNECT = 0x00001,
|
SC_MANAGER_CONNECT = 0x00001,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -514,8 +526,8 @@ namespace winsw
|
||||||
|
|
||||||
public SC_ACTION(SC_ACTION_TYPE type, TimeSpan delay)
|
public SC_ACTION(SC_ACTION_TYPE type, TimeSpan delay)
|
||||||
{
|
{
|
||||||
this.Type = type;
|
Type = type;
|
||||||
this.Delay = (uint)delay.TotalMilliseconds;
|
Delay = (uint)delay.TotalMilliseconds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
Download.cs
10
Download.cs
|
@ -1,17 +1,7 @@
|
||||||
using System;
|
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.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using WMI;
|
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Threading;
|
|
||||||
using Microsoft.Win32;
|
|
||||||
|
|
||||||
namespace winsw
|
namespace winsw
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Reflection;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
|
@ -85,11 +85,11 @@ namespace DynamicProxy
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ProxyFactory
|
public class ProxyFactory
|
||||||
{
|
{
|
||||||
private static ProxyFactory instance;
|
private static ProxyFactory _instance;
|
||||||
private static Object lockObj = new Object();
|
private static readonly Object LockObj = new Object();
|
||||||
|
|
||||||
private Hashtable typeMap = Hashtable.Synchronized(new Hashtable());
|
private readonly Hashtable _typeMap = Hashtable.Synchronized(new Hashtable());
|
||||||
private static readonly Hashtable opCodeTypeMapper = new Hashtable();
|
private static readonly Hashtable OpCodeTypeMapper = new Hashtable();
|
||||||
|
|
||||||
private const string PROXY_SUFFIX = "Proxy";
|
private const string PROXY_SUFFIX = "Proxy";
|
||||||
private const string ASSEMBLY_NAME = "ProxyAssembly";
|
private const string ASSEMBLY_NAME = "ProxyAssembly";
|
||||||
|
@ -100,14 +100,14 @@ namespace DynamicProxy
|
||||||
// return types, used in the Emit process.
|
// return types, used in the Emit process.
|
||||||
static ProxyFactory()
|
static ProxyFactory()
|
||||||
{
|
{
|
||||||
opCodeTypeMapper.Add(typeof(System.Boolean), OpCodes.Ldind_I1);
|
OpCodeTypeMapper.Add(typeof(Boolean), OpCodes.Ldind_I1);
|
||||||
opCodeTypeMapper.Add(typeof(System.Int16), OpCodes.Ldind_I2);
|
OpCodeTypeMapper.Add(typeof(Int16), OpCodes.Ldind_I2);
|
||||||
opCodeTypeMapper.Add(typeof(System.Int32), OpCodes.Ldind_I4);
|
OpCodeTypeMapper.Add(typeof(Int32), OpCodes.Ldind_I4);
|
||||||
opCodeTypeMapper.Add(typeof(System.Int64), OpCodes.Ldind_I8);
|
OpCodeTypeMapper.Add(typeof(Int64), OpCodes.Ldind_I8);
|
||||||
opCodeTypeMapper.Add(typeof(System.Double), OpCodes.Ldind_R8);
|
OpCodeTypeMapper.Add(typeof(Double), OpCodes.Ldind_R8);
|
||||||
opCodeTypeMapper.Add(typeof(System.Single), OpCodes.Ldind_R4);
|
OpCodeTypeMapper.Add(typeof(Single), OpCodes.Ldind_R4);
|
||||||
opCodeTypeMapper.Add(typeof(System.UInt16), OpCodes.Ldind_U2);
|
OpCodeTypeMapper.Add(typeof(UInt16), OpCodes.Ldind_U2);
|
||||||
opCodeTypeMapper.Add(typeof(System.UInt32), OpCodes.Ldind_U4);
|
OpCodeTypeMapper.Add(typeof(UInt32), OpCodes.Ldind_U4);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProxyFactory()
|
private ProxyFactory()
|
||||||
|
@ -116,21 +116,21 @@ namespace DynamicProxy
|
||||||
|
|
||||||
public static ProxyFactory GetInstance()
|
public static ProxyFactory GetInstance()
|
||||||
{
|
{
|
||||||
if (instance == null)
|
if (_instance == null)
|
||||||
{
|
{
|
||||||
CreateInstance();
|
CreateInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
return instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CreateInstance()
|
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)
|
public Object Create(IProxyInvocationHandler handler, Type objType, bool isObjInterface)
|
||||||
{
|
{
|
||||||
string typeName = objType.FullName + PROXY_SUFFIX;
|
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
|
// 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.
|
// 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);
|
type = CreateType(handler, objType.GetInterfaces(), typeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
typeMap.Add(typeName, type);
|
_typeMap.Add(typeName, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return a new instance of the type.
|
// return a new instance of the type.
|
||||||
|
@ -171,7 +171,7 @@ namespace DynamicProxy
|
||||||
|
|
||||||
if (handler != null && interfaces != null)
|
if (handler != null && interfaces != null)
|
||||||
{
|
{
|
||||||
Type objType = typeof(System.Object);
|
Type objType = typeof(Object);
|
||||||
Type handlerType = typeof(IProxyInvocationHandler);
|
Type handlerType = typeof(IProxyInvocationHandler);
|
||||||
|
|
||||||
AppDomain domain = Thread.GetDomain();
|
AppDomain domain = Thread.GetDomain();
|
||||||
|
@ -316,7 +316,7 @@ namespace DynamicProxy
|
||||||
} else if ( !methodInfo.ReturnType.IsPrimitive ) {
|
} else if ( !methodInfo.ReturnType.IsPrimitive ) {
|
||||||
methodIL.Emit( OpCodes.Ldobj, methodInfo.ReturnType );
|
methodIL.Emit( OpCodes.Ldobj, methodInfo.ReturnType );
|
||||||
} else {
|
} else {
|
||||||
methodIL.Emit( (OpCode) opCodeTypeMapper[ methodInfo.ReturnType ] );
|
methodIL.Emit( (OpCode) OpCodeTypeMapper[ methodInfo.ReturnType ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace winsw
|
namespace winsw
|
||||||
|
|
125
LogAppenders.cs
125
LogAppenders.cs
|
@ -1,9 +1,10 @@
|
||||||
using System.IO;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace winsw
|
namespace winsw
|
||||||
{
|
{
|
||||||
|
// ReSharper disable once InconsistentNaming
|
||||||
public interface EventLogger
|
public interface EventLogger
|
||||||
{
|
{
|
||||||
void LogEvent(string message);
|
void LogEvent(string message);
|
||||||
|
@ -15,24 +16,13 @@ namespace winsw
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class LogHandler
|
public abstract class LogHandler
|
||||||
{
|
{
|
||||||
private EventLogger eventLogger;
|
// ReSharper disable once InconsistentNaming
|
||||||
|
|
||||||
public abstract void log(Stream outputStream, Stream errorStream);
|
public abstract void log(Stream outputStream, Stream errorStream);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Error and information about logging should be reported here.
|
/// Error and information about logging should be reported here.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public EventLogger EventLogger
|
public EventLogger EventLogger { set; get; }
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
this.eventLogger = value;
|
|
||||||
}
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this.eventLogger;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convenience method to copy stuff from StreamReader to StreamWriter
|
/// Convenience method to copy stuff from StreamReader to StreamWriter
|
||||||
|
@ -73,59 +63,32 @@ namespace winsw
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class AbstractFileLogAppender : LogHandler
|
public abstract class AbstractFileLogAppender : LogHandler
|
||||||
{
|
{
|
||||||
private string baseLogFileName;
|
protected string BaseLogFileName { private set; get; }
|
||||||
|
|
||||||
public AbstractFileLogAppender(string logDirectory, string baseName)
|
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
|
public abstract class SimpleLogAppender : AbstractFileLogAppender
|
||||||
{
|
{
|
||||||
|
public FileMode FileMode { private set; get; }
|
||||||
private FileMode fileMode;
|
public string OutputLogFileName { private set; get; }
|
||||||
private string outputLogFileName;
|
public string ErrorLogFileName { private set; get; }
|
||||||
private string errorLogFileName;
|
|
||||||
|
|
||||||
public SimpleLogAppender(string logDirectory, string baseName, FileMode fileMode)
|
public SimpleLogAppender(string logDirectory, string baseName, FileMode fileMode)
|
||||||
: base(logDirectory, baseName)
|
: base(logDirectory, baseName)
|
||||||
{
|
{
|
||||||
this.fileMode = fileMode;
|
FileMode = fileMode;
|
||||||
this.outputLogFileName = BaseLogFileName + ".out.log";
|
OutputLogFileName = BaseLogFileName + ".out.log";
|
||||||
this.errorLogFileName = BaseLogFileName + ".err.log";
|
ErrorLogFileName = BaseLogFileName + ".err.log";
|
||||||
}
|
|
||||||
|
|
||||||
public string OutputLogFileName
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this.outputLogFileName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ErrorLogFileName
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this.errorLogFileName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void log(Stream outputStream, Stream errorStream)
|
public override void log(Stream outputStream, Stream errorStream)
|
||||||
{
|
{
|
||||||
new Thread(delegate() { CopyStream(outputStream, new FileStream(outputLogFileName, fileMode)); }).Start();
|
new Thread(delegate() { CopyStream(outputStream, new FileStream(OutputLogFileName, FileMode)); }).Start();
|
||||||
new Thread(delegate() { CopyStream(errorStream, new FileStream(errorLogFileName, fileMode)); }).Start();
|
new Thread(delegate() { CopyStream(errorStream, new FileStream(ErrorLogFileName, FileMode)); }).Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,31 +122,14 @@ namespace winsw
|
||||||
|
|
||||||
public class TimeBasedRollingLogAppender : AbstractFileLogAppender
|
public class TimeBasedRollingLogAppender : AbstractFileLogAppender
|
||||||
{
|
{
|
||||||
|
public string Pattern { get; private set; }
|
||||||
private string pattern;
|
public int Period { get; private set; }
|
||||||
private int period;
|
|
||||||
|
|
||||||
public string Pattern
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return pattern;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Period
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return period;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeBasedRollingLogAppender(string logDirectory, string baseName, string pattern, int period)
|
public TimeBasedRollingLogAppender(string logDirectory, string baseName, string pattern, int period)
|
||||||
: base(logDirectory, baseName)
|
: base(logDirectory, baseName)
|
||||||
{
|
{
|
||||||
this.pattern = pattern;
|
Pattern = pattern;
|
||||||
this.period = period;
|
Period = period;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void log(Stream outputStream, Stream errorStream)
|
public override void log(Stream outputStream, Stream errorStream)
|
||||||
|
@ -197,7 +143,7 @@ namespace winsw
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void CopyStreamWithDateRotation(Stream data, string ext)
|
private void CopyStreamWithDateRotation(Stream data, string ext)
|
||||||
{
|
{
|
||||||
PeriodicRollingCalendar periodicRollingCalendar = new PeriodicRollingCalendar(pattern, period);
|
PeriodicRollingCalendar periodicRollingCalendar = new PeriodicRollingCalendar(Pattern, Period);
|
||||||
periodicRollingCalendar.init();
|
periodicRollingCalendar.init();
|
||||||
|
|
||||||
byte[] buf = new byte[1024];
|
byte[] buf = new byte[1024];
|
||||||
|
@ -254,35 +200,24 @@ namespace winsw
|
||||||
|
|
||||||
public class SizeBasedRollingLogAppender : AbstractFileLogAppender
|
public class SizeBasedRollingLogAppender : AbstractFileLogAppender
|
||||||
{
|
{
|
||||||
|
// ReSharper disable once InconsistentNaming
|
||||||
public static int BYTES_PER_KB = 1024;
|
public static int BYTES_PER_KB = 1024;
|
||||||
|
// ReSharper disable once InconsistentNaming
|
||||||
public static int BYTES_PER_MB = 1024 * BYTES_PER_KB;
|
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.
|
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;
|
public static int DEFAULT_FILES_TO_KEEP = 8;
|
||||||
|
|
||||||
private int sizeThreshold;
|
public int SizeTheshold { private set; get; }
|
||||||
private int filesToKeep;
|
|
||||||
|
|
||||||
public int SizeTheshold
|
public int FilesToKeep { private set; get; }
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return sizeThreshold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int FilesToKeep
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return filesToKeep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SizeBasedRollingLogAppender(string logDirectory, string baseName, int sizeThreshold, int filesToKeep)
|
public SizeBasedRollingLogAppender(string logDirectory, string baseName, int sizeThreshold, int filesToKeep)
|
||||||
: base(logDirectory, baseName)
|
: base(logDirectory, baseName)
|
||||||
{
|
{
|
||||||
this.sizeThreshold = sizeThreshold;
|
SizeTheshold = sizeThreshold;
|
||||||
this.filesToKeep = filesToKeep;
|
FilesToKeep = filesToKeep;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SizeBasedRollingLogAppender(string logDirectory, string baseName)
|
public SizeBasedRollingLogAppender(string logDirectory, string baseName)
|
||||||
|
@ -307,7 +242,7 @@ namespace winsw
|
||||||
{
|
{
|
||||||
int len = data.Read(buf, 0, buf.Length);
|
int len = data.Read(buf, 0, buf.Length);
|
||||||
if (len == 0) break; // EOF
|
if (len == 0) break; // EOF
|
||||||
if (sz + len < sizeThreshold)
|
if (sz + len < SizeTheshold)
|
||||||
{// typical case. write the whole thing into the current file
|
{// typical case. write the whole thing into the current file
|
||||||
w.Write(buf, 0, len);
|
w.Write(buf, 0, len);
|
||||||
sz += len;
|
sz += len;
|
||||||
|
@ -319,7 +254,7 @@ namespace winsw
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
if (buf[i] != 0x0A) continue;
|
if (buf[i] != 0x0A) continue;
|
||||||
if (sz + i < sizeThreshold) continue;
|
if (sz + i < SizeTheshold) continue;
|
||||||
|
|
||||||
// at the line boundary and exceeded the rotation unit.
|
// at the line boundary and exceeded the rotation unit.
|
||||||
// time to rotate.
|
// time to rotate.
|
||||||
|
@ -329,7 +264,7 @@ namespace winsw
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for (int j = filesToKeep; j >= 1; j--)
|
for (int j = FilesToKeep; j >= 1; j--)
|
||||||
{
|
{
|
||||||
string dst = BaseLogFileName + "." + (j - 1) + ext;
|
string dst = BaseLogFileName + "." + (j - 1) + ext;
|
||||||
string src = BaseLogFileName + "." + (j - 2) + ext;
|
string src = BaseLogFileName + "." + (j - 2) + ext;
|
||||||
|
|
71
Main.cs
71
Main.cs
|
@ -1,18 +1,15 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Data;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Management;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
|
||||||
using WMI;
|
|
||||||
using System.Xml;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System.Management;
|
using WMI;
|
||||||
|
using ServiceType = WMI.ServiceType;
|
||||||
|
|
||||||
namespace winsw
|
namespace winsw
|
||||||
{
|
{
|
||||||
|
@ -20,26 +17,26 @@ namespace winsw
|
||||||
{
|
{
|
||||||
private SERVICE_STATUS wrapperServiceStatus;
|
private SERVICE_STATUS wrapperServiceStatus;
|
||||||
|
|
||||||
private Process process = new Process();
|
private readonly Process process = new Process();
|
||||||
private ServiceDescriptor descriptor;
|
private readonly ServiceDescriptor descriptor;
|
||||||
private Dictionary<string, string> envs;
|
private Dictionary<string, string> _envs;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates to the watch dog thread that we are going to terminate the process,
|
/// 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.
|
/// so don't try to kill us when the child exits.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool orderlyShutdown;
|
private bool _orderlyShutdown;
|
||||||
private bool systemShuttingdown;
|
private bool _systemShuttingdown;
|
||||||
|
|
||||||
public WrapperService()
|
public WrapperService()
|
||||||
{
|
{
|
||||||
this.descriptor = new ServiceDescriptor();
|
descriptor = new ServiceDescriptor();
|
||||||
this.ServiceName = descriptor.Id;
|
ServiceName = descriptor.Id;
|
||||||
this.CanShutdown = true;
|
CanShutdown = true;
|
||||||
this.CanStop = true;
|
CanStop = true;
|
||||||
this.CanPauseAndContinue = false;
|
CanPauseAndContinue = false;
|
||||||
this.AutoLog = true;
|
AutoLog = true;
|
||||||
this.systemShuttingdown = false;
|
_systemShuttingdown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -132,7 +129,7 @@ namespace winsw
|
||||||
|
|
||||||
public void LogEvent(String message)
|
public void LogEvent(String message)
|
||||||
{
|
{
|
||||||
if (systemShuttingdown)
|
if (_systemShuttingdown)
|
||||||
{
|
{
|
||||||
/* NOP - cannot call EventLog because of shutdown. */
|
/* NOP - cannot call EventLog because of shutdown. */
|
||||||
}
|
}
|
||||||
|
@ -151,7 +148,7 @@ namespace winsw
|
||||||
|
|
||||||
public void LogEvent(String message, EventLogEntryType type)
|
public void LogEvent(String message, EventLogEntryType type)
|
||||||
{
|
{
|
||||||
if (systemShuttingdown)
|
if (_systemShuttingdown)
|
||||||
{
|
{
|
||||||
/* NOP - cannot call EventLog because of shutdown. */
|
/* NOP - cannot call EventLog because of shutdown. */
|
||||||
}
|
}
|
||||||
|
@ -190,10 +187,10 @@ namespace winsw
|
||||||
|
|
||||||
protected override void OnStart(string[] _)
|
protected override void OnStart(string[] _)
|
||||||
{
|
{
|
||||||
envs = descriptor.EnvironmentVariables;
|
_envs = descriptor.EnvironmentVariables;
|
||||||
foreach (string key in envs.Keys)
|
foreach (string key in _envs.Keys)
|
||||||
{
|
{
|
||||||
LogEvent("envar " + key + '=' + envs[key]);
|
LogEvent("envar " + key + '=' + _envs[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleFileCopies();
|
HandleFileCopies();
|
||||||
|
@ -242,7 +239,7 @@ namespace winsw
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.systemShuttingdown = true;
|
_systemShuttingdown = true;
|
||||||
StopIt();
|
StopIt();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -273,7 +270,7 @@ namespace winsw
|
||||||
string stoparguments = descriptor.Stoparguments;
|
string stoparguments = descriptor.Stoparguments;
|
||||||
LogEvent("Stopping " + descriptor.Id);
|
LogEvent("Stopping " + descriptor.Id);
|
||||||
WriteEvent("Stopping " + descriptor.Id);
|
WriteEvent("Stopping " + descriptor.Id);
|
||||||
orderlyShutdown = true;
|
_orderlyShutdown = true;
|
||||||
|
|
||||||
if (stoparguments == null)
|
if (stoparguments == null)
|
||||||
{
|
{
|
||||||
|
@ -309,7 +306,7 @@ namespace winsw
|
||||||
SignalShutdownComplete();
|
SignalShutdownComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (systemShuttingdown && descriptor.BeepOnShutdown)
|
if (_systemShuttingdown && descriptor.BeepOnShutdown)
|
||||||
{
|
{
|
||||||
Console.Beep();
|
Console.Beep();
|
||||||
}
|
}
|
||||||
|
@ -386,7 +383,7 @@ namespace winsw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WaitForProcessToExit(Process process)
|
private void WaitForProcessToExit(Process processoWait)
|
||||||
{
|
{
|
||||||
SignalShutdownPending();
|
SignalShutdownPending();
|
||||||
|
|
||||||
|
@ -394,7 +391,7 @@ namespace winsw
|
||||||
{
|
{
|
||||||
// WriteEvent("WaitForProcessToExit [start]");
|
// WriteEvent("WaitForProcessToExit [start]");
|
||||||
|
|
||||||
while (!process.WaitForExit(descriptor.SleepTime.Milliseconds))
|
while (!processoWait.WaitForExit(descriptor.SleepTime.Milliseconds))
|
||||||
{
|
{
|
||||||
SignalShutdownPending();
|
SignalShutdownPending();
|
||||||
// WriteEvent("WaitForProcessToExit [repeat]");
|
// WriteEvent("WaitForProcessToExit [repeat]");
|
||||||
|
@ -410,7 +407,7 @@ namespace winsw
|
||||||
|
|
||||||
private void SignalShutdownPending()
|
private void SignalShutdownPending()
|
||||||
{
|
{
|
||||||
IntPtr handle = this.ServiceHandle;
|
IntPtr handle = ServiceHandle;
|
||||||
wrapperServiceStatus.checkPoint++;
|
wrapperServiceStatus.checkPoint++;
|
||||||
wrapperServiceStatus.waitHint = descriptor.WaitHint.Milliseconds;
|
wrapperServiceStatus.waitHint = descriptor.WaitHint.Milliseconds;
|
||||||
// WriteEvent("SignalShutdownPending " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint);
|
// WriteEvent("SignalShutdownPending " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint);
|
||||||
|
@ -420,7 +417,7 @@ namespace winsw
|
||||||
|
|
||||||
private void SignalShutdownComplete()
|
private void SignalShutdownComplete()
|
||||||
{
|
{
|
||||||
IntPtr handle = this.ServiceHandle;
|
IntPtr handle = ServiceHandle;
|
||||||
wrapperServiceStatus.checkPoint++;
|
wrapperServiceStatus.checkPoint++;
|
||||||
// WriteEvent("SignalShutdownComplete " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint);
|
// WriteEvent("SignalShutdownComplete " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint);
|
||||||
wrapperServiceStatus.currentState = (int)State.SERVICE_STOPPED;
|
wrapperServiceStatus.currentState = (int)State.SERVICE_STOPPED;
|
||||||
|
@ -439,8 +436,8 @@ namespace winsw
|
||||||
ps.RedirectStandardOutput = true;
|
ps.RedirectStandardOutput = true;
|
||||||
ps.RedirectStandardError = true;
|
ps.RedirectStandardError = true;
|
||||||
|
|
||||||
foreach (string key in envs.Keys)
|
foreach (string key in _envs.Keys)
|
||||||
System.Environment.SetEnvironmentVariable(key, envs[key]);
|
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)
|
// 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();
|
process.Start();
|
||||||
|
@ -451,14 +448,14 @@ namespace winsw
|
||||||
process.PriorityClass = priority;
|
process.PriorityClass = priority;
|
||||||
|
|
||||||
// monitor the completion of the process
|
// monitor the completion of the process
|
||||||
StartThread(delegate()
|
StartThread(delegate
|
||||||
{
|
{
|
||||||
string msg = process.Id + " - " + process.StartInfo.FileName + " " + process.StartInfo.Arguments;
|
string msg = process.Id + " - " + process.StartInfo.FileName + " " + process.StartInfo.Arguments;
|
||||||
process.WaitForExit();
|
process.WaitForExit();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (orderlyShutdown)
|
if (_orderlyShutdown)
|
||||||
{
|
{
|
||||||
LogEvent("Child process [" + msg + "] terminated with " + process.ExitCode, EventLogEntryType.Information);
|
LogEvent("Child process [" + msg + "] terminated with " + process.ExitCode, EventLogEntryType.Information);
|
||||||
}
|
}
|
||||||
|
@ -585,7 +582,7 @@ namespace winsw
|
||||||
d.Id,
|
d.Id,
|
||||||
d.Caption,
|
d.Caption,
|
||||||
"\"" + d.ExecutablePath + "\"",
|
"\"" + d.ExecutablePath + "\"",
|
||||||
WMI.ServiceType.OwnProcess,
|
ServiceType.OwnProcess,
|
||||||
ErrorControl.UserNotified,
|
ErrorControl.UserNotified,
|
||||||
StartMode.Automatic,
|
StartMode.Automatic,
|
||||||
d.Interactive,
|
d.Interactive,
|
||||||
|
@ -688,7 +685,7 @@ namespace winsw
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ServiceBase.Run(new WrapperService());
|
Run(new WrapperService());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ReadPassword()
|
private static string ReadPassword()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Data;
|
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
namespace winsw
|
namespace winsw
|
||||||
{
|
{
|
||||||
|
@ -8,23 +9,22 @@ namespace winsw
|
||||||
**/
|
**/
|
||||||
public class PeriodicRollingCalendar
|
public class PeriodicRollingCalendar
|
||||||
{
|
{
|
||||||
private PeriodicityType _periodicityType;
|
private readonly string _format;
|
||||||
private string _format;
|
private readonly long _period;
|
||||||
private long _period;
|
|
||||||
private DateTime _currentRoll;
|
private DateTime _currentRoll;
|
||||||
private DateTime _nextRoll;
|
private DateTime _nextRoll;
|
||||||
|
|
||||||
public PeriodicRollingCalendar(string format, long period)
|
public PeriodicRollingCalendar(string format, long period)
|
||||||
{
|
{
|
||||||
this._format = format;
|
_format = format;
|
||||||
this._period = period;
|
_period = period;
|
||||||
this._currentRoll = DateTime.Now;
|
_currentRoll = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init()
|
public void init()
|
||||||
{
|
{
|
||||||
this._periodicityType = determinePeriodicityType();
|
periodicityType = determinePeriodicityType();
|
||||||
this._nextRoll = nextTriggeringTime(this._currentRoll, this._period);
|
_nextRoll = nextTriggeringTime(_currentRoll, _period);
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum PeriodicityType
|
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
|
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
|
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)
|
private DateTime nextTriggeringTime(DateTime input, long increment)
|
||||||
{
|
{
|
||||||
DateTime output;
|
DateTime output;
|
||||||
switch (_periodicityType)
|
switch (periodicityType)
|
||||||
{
|
{
|
||||||
case PeriodicityType.TOP_OF_MILLISECOND:
|
case PeriodicityType.TOP_OF_MILLISECOND:
|
||||||
output = new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, input.Second, input.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);
|
output = output.AddDays(increment);
|
||||||
return output;
|
return output;
|
||||||
default:
|
default:
|
||||||
throw new Exception("invalid periodicity type: " + _periodicityType);
|
throw new Exception("invalid periodicity type: " + periodicityType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PeriodicityType periodicityType
|
public PeriodicityType periodicityType { get; set; }
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
this._periodicityType = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean shouldRoll
|
public Boolean shouldRoll
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
DateTime now = DateTime.Now;
|
DateTime now = DateTime.Now;
|
||||||
if (now > this._nextRoll)
|
if (now > _nextRoll)
|
||||||
{
|
{
|
||||||
this._currentRoll = now;
|
_currentRoll = now;
|
||||||
this._nextRoll = nextTriggeringTime(now, this._period);
|
_nextRoll = nextTriggeringTime(now, _period);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -114,7 +108,7 @@ namespace winsw
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return this._currentRoll.ToString(this._format);
|
return _currentRoll.ToString(_format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
[assembly: AssemblyTitle("Windows Service Wrapper")]
|
[assembly: AssemblyTitle("Windows Service Wrapper")]
|
||||||
|
|
|
@ -1,18 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Data;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.ServiceProcess;
|
|
||||||
using System.Text;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Reflection;
|
||||||
using WMI;
|
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Threading;
|
|
||||||
using Microsoft.Win32;
|
|
||||||
|
|
||||||
namespace winsw
|
namespace winsw
|
||||||
{
|
{
|
||||||
|
@ -21,6 +13,7 @@ namespace winsw
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ServiceDescriptor
|
public class ServiceDescriptor
|
||||||
{
|
{
|
||||||
|
// ReSharper disable once InconsistentNaming
|
||||||
protected readonly XmlDocument dom = new XmlDocument();
|
protected readonly XmlDocument dom = new XmlDocument();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -132,7 +125,7 @@ namespace winsw
|
||||||
private TimeSpan ParseTimeSpan(string v)
|
private TimeSpan ParseTimeSpan(string v)
|
||||||
{
|
{
|
||||||
v = v.Trim();
|
v = v.Trim();
|
||||||
foreach (var s in SUFFIX)
|
foreach (var s in Suffix)
|
||||||
{
|
{
|
||||||
if (v.EndsWith(s.Key))
|
if (v.EndsWith(s.Key))
|
||||||
{
|
{
|
||||||
|
@ -142,7 +135,7 @@ namespace winsw
|
||||||
return TimeSpan.FromMilliseconds(int.Parse(v));
|
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 },
|
{ "ms", 1 },
|
||||||
{ "sec", 1000L },
|
{ "sec", 1000L },
|
||||||
{ "secs", 1000L },
|
{ "secs", 1000L },
|
||||||
|
@ -362,7 +355,7 @@ namespace winsw
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
System.Collections.ArrayList serviceDependencies = new System.Collections.ArrayList();
|
ArrayList serviceDependencies = new ArrayList();
|
||||||
|
|
||||||
foreach (XmlNode depend in dom.SelectNodes("//depend"))
|
foreach (XmlNode depend in dom.SelectNodes("//depend"))
|
||||||
{
|
{
|
||||||
|
@ -548,13 +541,16 @@ namespace winsw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReSharper disable once InconsistentNaming
|
||||||
protected string serviceAccountDomain
|
protected string serviceAccountDomain
|
||||||
{
|
{
|
||||||
get{
|
get
|
||||||
|
{
|
||||||
return GetServiceAccountPart("domain");
|
return GetServiceAccountPart("domain");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReSharper disable once InconsistentNaming
|
||||||
protected string serviceAccountName
|
protected string serviceAccountName
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -587,7 +583,7 @@ namespace winsw
|
||||||
{
|
{
|
||||||
if (AllowServiceLogon != null)
|
if (AllowServiceLogon != null)
|
||||||
{
|
{
|
||||||
bool parsedvalue = false;
|
bool parsedvalue;
|
||||||
if (Boolean.TryParse(AllowServiceLogon, out parsedvalue))
|
if (Boolean.TryParse(AllowServiceLogon, out parsedvalue))
|
||||||
{
|
{
|
||||||
return parsedvalue;
|
return parsedvalue;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace winsw
|
namespace winsw
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
using NUnit.Framework;
|
using System;
|
||||||
using winsw;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Xml;
|
using NUnit.Framework;
|
||||||
|
using winsw;
|
||||||
|
|
||||||
namespace winswTests
|
namespace winswTests
|
||||||
{
|
{
|
||||||
using System;
|
|
||||||
|
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class ServiceDescriptorTests
|
public class ServiceDescriptorTests
|
||||||
{
|
{
|
||||||
|
|
||||||
private ServiceDescriptor extendedServiceDescriptor;
|
private ServiceDescriptor _extendedServiceDescriptor;
|
||||||
|
|
||||||
private const string ExpectedWorkingDirectory = @"Z:\Path\SubPath";
|
private const string ExpectedWorkingDirectory = @"Z:\Path\SubPath";
|
||||||
private const string Username = "User";
|
private const string Username = "User";
|
||||||
|
@ -22,7 +20,7 @@ namespace winswTests
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp()
|
public void SetUp()
|
||||||
{
|
{
|
||||||
const string SeedXml = "<service>"
|
const string seedXml = "<service>"
|
||||||
+ "<id>service.exe</id>"
|
+ "<id>service.exe</id>"
|
||||||
+ "<name>Service</name>"
|
+ "<name>Service</name>"
|
||||||
+ "<description>The service.</description>"
|
+ "<description>The service.</description>"
|
||||||
|
@ -40,34 +38,34 @@ namespace winswTests
|
||||||
+ "</workingdirectory>"
|
+ "</workingdirectory>"
|
||||||
+ @"<logpath>C:\logs</logpath>"
|
+ @"<logpath>C:\logs</logpath>"
|
||||||
+ "</service>";
|
+ "</service>";
|
||||||
extendedServiceDescriptor = ServiceDescriptor.FromXML(SeedXml);
|
_extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void VerifyWorkingDirectory()
|
public void VerifyWorkingDirectory()
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + extendedServiceDescriptor.WorkingDirectory);
|
Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory);
|
||||||
Assert.That(extendedServiceDescriptor.WorkingDirectory, Is.EqualTo(ExpectedWorkingDirectory));
|
Assert.That(_extendedServiceDescriptor.WorkingDirectory, Is.EqualTo(ExpectedWorkingDirectory));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void VerifyServiceLogonRight()
|
public void VerifyServiceLogonRight()
|
||||||
{
|
{
|
||||||
Assert.That(extendedServiceDescriptor.AllowServiceAcountLogonRight, Is.EqualTo(true));
|
Assert.That(_extendedServiceDescriptor.AllowServiceAcountLogonRight, Is.EqualTo(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void VerifyUsername()
|
public void VerifyUsername()
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + extendedServiceDescriptor.WorkingDirectory);
|
Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory);
|
||||||
Assert.That(extendedServiceDescriptor.ServiceAccountUser, Is.EqualTo(Domain + "\\" + Username));
|
Assert.That(_extendedServiceDescriptor.ServiceAccountUser, Is.EqualTo(Domain + "\\" + Username));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void VerifyPassword()
|
public void VerifyPassword()
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + extendedServiceDescriptor.WorkingDirectory);
|
Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory);
|
||||||
Assert.That(extendedServiceDescriptor.ServiceAccountPassword, Is.EqualTo(Password));
|
Assert.That(_extendedServiceDescriptor.ServiceAccountPassword, Is.EqualTo(Password));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -86,16 +84,16 @@ namespace winswTests
|
||||||
[Test]
|
[Test]
|
||||||
public void StopParentProcessFirstIsFalseByDefault()
|
public void StopParentProcessFirstIsFalseByDefault()
|
||||||
{
|
{
|
||||||
Assert.False(extendedServiceDescriptor.StopParentProcessFirst);
|
Assert.False(_extendedServiceDescriptor.StopParentProcessFirst);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void CanParseStopParentProcessFirst()
|
public void CanParseStopParentProcessFirst()
|
||||||
{
|
{
|
||||||
const string SeedXml = "<service>"
|
const string seedXml = "<service>"
|
||||||
+ "<stopparentprocessfirst>true</stopparentprocessfirst>"
|
+ "<stopparentprocessfirst>true</stopparentprocessfirst>"
|
||||||
+ "</service>";
|
+ "</service>";
|
||||||
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
|
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
|
||||||
|
|
||||||
Assert.True(serviceDescriptor.StopParentProcessFirst);
|
Assert.True(serviceDescriptor.StopParentProcessFirst);
|
||||||
}
|
}
|
||||||
|
@ -103,10 +101,10 @@ namespace winswTests
|
||||||
[Test]
|
[Test]
|
||||||
public void CanParseStopTimeout()
|
public void CanParseStopTimeout()
|
||||||
{
|
{
|
||||||
const string SeedXml = "<service>"
|
const string seedXml = "<service>"
|
||||||
+ "<stoptimeout>60sec</stoptimeout>"
|
+ "<stoptimeout>60sec</stoptimeout>"
|
||||||
+ "</service>";
|
+ "</service>";
|
||||||
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
|
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
|
||||||
|
|
||||||
Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromSeconds(60)));
|
Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromSeconds(60)));
|
||||||
}
|
}
|
||||||
|
@ -114,10 +112,10 @@ namespace winswTests
|
||||||
[Test]
|
[Test]
|
||||||
public void CanParseStopTimeoutFromMinutes()
|
public void CanParseStopTimeoutFromMinutes()
|
||||||
{
|
{
|
||||||
const string SeedXml = "<service>"
|
const string seedXml = "<service>"
|
||||||
+ "<stoptimeout>10min</stoptimeout>"
|
+ "<stoptimeout>10min</stoptimeout>"
|
||||||
+ "</service>";
|
+ "</service>";
|
||||||
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
|
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
|
||||||
|
|
||||||
Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromMinutes(10)));
|
Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromMinutes(10)));
|
||||||
}
|
}
|
||||||
|
@ -125,7 +123,7 @@ namespace winswTests
|
||||||
[Test]
|
[Test]
|
||||||
public void LogModeRollBySize()
|
public void LogModeRollBySize()
|
||||||
{
|
{
|
||||||
const string SeedXml = "<service>"
|
const string seedXml = "<service>"
|
||||||
+ "<logpath>c:\\</logpath>"
|
+ "<logpath>c:\\</logpath>"
|
||||||
+ "<log mode=\"roll-by-size\">"
|
+ "<log mode=\"roll-by-size\">"
|
||||||
+ "<sizeThreshold>112</sizeThreshold>"
|
+ "<sizeThreshold>112</sizeThreshold>"
|
||||||
|
@ -133,7 +131,7 @@ namespace winswTests
|
||||||
+ "</log>"
|
+ "</log>"
|
||||||
+ "</service>";
|
+ "</service>";
|
||||||
|
|
||||||
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
|
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
|
||||||
serviceDescriptor.BaseName = "service";
|
serviceDescriptor.BaseName = "service";
|
||||||
|
|
||||||
var logHandler = serviceDescriptor.LogHandler as SizeBasedRollingLogAppender;
|
var logHandler = serviceDescriptor.LogHandler as SizeBasedRollingLogAppender;
|
||||||
|
@ -145,7 +143,7 @@ namespace winswTests
|
||||||
[Test]
|
[Test]
|
||||||
public void LogModeRollByTime()
|
public void LogModeRollByTime()
|
||||||
{
|
{
|
||||||
const string SeedXml = "<service>"
|
const string seedXml = "<service>"
|
||||||
+ "<logpath>c:\\</logpath>"
|
+ "<logpath>c:\\</logpath>"
|
||||||
+ "<log mode=\"roll-by-time\">"
|
+ "<log mode=\"roll-by-time\">"
|
||||||
+ "<period>7</period>"
|
+ "<period>7</period>"
|
||||||
|
@ -153,7 +151,7 @@ namespace winswTests
|
||||||
+ "</log>"
|
+ "</log>"
|
||||||
+ "</service>";
|
+ "</service>";
|
||||||
|
|
||||||
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
|
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
|
||||||
serviceDescriptor.BaseName = "service";
|
serviceDescriptor.BaseName = "service";
|
||||||
|
|
||||||
var logHandler = serviceDescriptor.LogHandler as TimeBasedRollingLogAppender;
|
var logHandler = serviceDescriptor.LogHandler as TimeBasedRollingLogAppender;
|
||||||
|
@ -165,7 +163,7 @@ namespace winswTests
|
||||||
[Test]
|
[Test]
|
||||||
public void VerifyServiceLogonRightGraceful()
|
public void VerifyServiceLogonRightGraceful()
|
||||||
{
|
{
|
||||||
const string SeedXml="<service>"
|
const string seedXml="<service>"
|
||||||
+ "<serviceaccount>"
|
+ "<serviceaccount>"
|
||||||
+ "<domain>" + Domain + "</domain>"
|
+ "<domain>" + Domain + "</domain>"
|
||||||
+ "<user>" + Username + "</user>"
|
+ "<user>" + Username + "</user>"
|
||||||
|
@ -173,20 +171,20 @@ namespace winswTests
|
||||||
+ "<allowservicelogon>true1</allowservicelogon>"
|
+ "<allowservicelogon>true1</allowservicelogon>"
|
||||||
+ "</serviceaccount>"
|
+ "</serviceaccount>"
|
||||||
+ "</service>";
|
+ "</service>";
|
||||||
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
|
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
|
||||||
Assert.That(serviceDescriptor.AllowServiceAcountLogonRight, Is.EqualTo(false));
|
Assert.That(serviceDescriptor.AllowServiceAcountLogonRight, Is.EqualTo(false));
|
||||||
}
|
}
|
||||||
[Test]
|
[Test]
|
||||||
public void VerifyServiceLogonRightOmitted()
|
public void VerifyServiceLogonRightOmitted()
|
||||||
{
|
{
|
||||||
const string SeedXml = "<service>"
|
const string seedXml = "<service>"
|
||||||
+ "<serviceaccount>"
|
+ "<serviceaccount>"
|
||||||
+ "<domain>" + Domain + "</domain>"
|
+ "<domain>" + Domain + "</domain>"
|
||||||
+ "<user>" + Username + "</user>"
|
+ "<user>" + Username + "</user>"
|
||||||
+ "<password>" + Password + "</password>"
|
+ "<password>" + Password + "</password>"
|
||||||
+ "</serviceaccount>"
|
+ "</serviceaccount>"
|
||||||
+ "</service>";
|
+ "</service>";
|
||||||
var serviceDescriptor = ServiceDescriptor.FromXML(SeedXml);
|
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
|
||||||
Assert.That(serviceDescriptor.AllowServiceAcountLogonRight, Is.EqualTo(false));
|
Assert.That(serviceDescriptor.AllowServiceAcountLogonRight, Is.EqualTo(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
42
Wmi.cs
42
Wmi.cs
|
@ -1,8 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Management;
|
using System.Management;
|
||||||
|
using System.Reflection;
|
||||||
using DynamicProxy;
|
using DynamicProxy;
|
||||||
|
|
||||||
namespace WMI
|
namespace WMI
|
||||||
|
@ -65,7 +63,7 @@ namespace WMI
|
||||||
public class WmiClassName : Attribute
|
public class WmiClassName : Attribute
|
||||||
{
|
{
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
public WmiClassName(string name) { this.Name = name; }
|
public WmiClassName(string name) { Name = name; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -107,7 +105,7 @@ namespace WMI
|
||||||
scope.Connect();
|
scope.Connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string capitalize(string s)
|
private static string Capitalize(string s)
|
||||||
{
|
{
|
||||||
return char.ToUpper(s[0]) + s.Substring(1);
|
return char.ToUpper(s[0]) + s.Substring(1);
|
||||||
}
|
}
|
||||||
|
@ -126,9 +124,9 @@ namespace WMI
|
||||||
|
|
||||||
class InstanceHandler : BaseHandler, IWmiObject
|
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)
|
public override object Invoke(object proxy, MethodInfo method, object[] args)
|
||||||
{
|
{
|
||||||
|
@ -140,37 +138,37 @@ namespace WMI
|
||||||
// TODO: proper property support
|
// TODO: proper property support
|
||||||
if (method.Name.StartsWith("set_"))
|
if (method.Name.StartsWith("set_"))
|
||||||
{
|
{
|
||||||
mo[method.Name.Substring(4)] = args[0];
|
_mo[method.Name.Substring(4)] = args[0];
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (method.Name.StartsWith("get_"))
|
if (method.Name.StartsWith("get_"))
|
||||||
{
|
{
|
||||||
return mo[method.Name.Substring(4)];
|
return _mo[method.Name.Substring(4)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// method invocations
|
// method invocations
|
||||||
ParameterInfo[] methodArgs = method.GetParameters();
|
ParameterInfo[] methodArgs = method.GetParameters();
|
||||||
|
|
||||||
ManagementBaseObject wmiArgs = mo.GetMethodParameters(method.Name);
|
ManagementBaseObject wmiArgs = _mo.GetMethodParameters(method.Name);
|
||||||
for (int i = 0; i < args.Length; i++)
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Commit()
|
public void Commit()
|
||||||
{
|
{
|
||||||
mo.Put();
|
_mo.Put();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClassHandler : BaseHandler
|
class ClassHandler : BaseHandler
|
||||||
{
|
{
|
||||||
private readonly ManagementClass mc;
|
private readonly ManagementClass _mc;
|
||||||
private readonly string wmiClass;
|
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)
|
public override object Invoke(object proxy, MethodInfo method, object[] args)
|
||||||
{
|
{
|
||||||
|
@ -179,14 +177,14 @@ namespace WMI
|
||||||
if (method.Name.StartsWith("Select"))
|
if (method.Name.StartsWith("Select"))
|
||||||
{
|
{
|
||||||
// select method to find instances
|
// 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++)
|
for (int i = 0; i < args.Length; i++)
|
||||||
{
|
{
|
||||||
if (i != 0) query += " AND ";
|
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();
|
ManagementObjectCollection results = searcher.Get();
|
||||||
// TODO: support collections
|
// TODO: support collections
|
||||||
foreach (ManagementObject manObject in results)
|
foreach (ManagementObject manObject in results)
|
||||||
|
@ -194,11 +192,11 @@ namespace WMI
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ManagementBaseObject wmiArgs = mc.GetMethodParameters(method.Name);
|
ManagementBaseObject wmiArgs = _mc.GetMethodParameters(method.Name);
|
||||||
for (int i = 0; i < args.Length; i++)
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue