mirror of https://github.com/winsw/winsw
Logging subsystem refactoring - use log4net (#145)
* Save the progress * Add log4net Log appender for Windows service events * Get rid of the IEventLogger API, we use log4net nowpull/165/head
parent
2db4fb2c31
commit
12c16e40a7
|
@ -0,0 +1,28 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
using winsw.Logging;
|
||||||
|
|
||||||
|
namespace winsw.Logging
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Implements caching of the WindowsService reference in WinSW.
|
||||||
|
/// </summary>
|
||||||
|
public class WrapperServiceEventLogProvider : IServiceEventLogProvider
|
||||||
|
{
|
||||||
|
public WrapperService service {get; set;}
|
||||||
|
|
||||||
|
public EventLog locate()
|
||||||
|
{
|
||||||
|
WrapperService _service = service;
|
||||||
|
if (_service != null && !_service.IsShuttingDown)
|
||||||
|
{
|
||||||
|
return _service.EventLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
// By default return null
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,10 +20,11 @@ using WMI;
|
||||||
using ServiceType = WMI.ServiceType;
|
using ServiceType = WMI.ServiceType;
|
||||||
using winsw.Native;
|
using winsw.Native;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using winsw.Logging;
|
||||||
|
|
||||||
namespace winsw
|
namespace winsw
|
||||||
{
|
{
|
||||||
public class WrapperService : ServiceBase, EventLogger, IEventWriter
|
public class WrapperService : ServiceBase, EventLogger
|
||||||
{
|
{
|
||||||
private SERVICE_STATUS _wrapperServiceStatus;
|
private SERVICE_STATUS _wrapperServiceStatus;
|
||||||
|
|
||||||
|
@ -34,6 +35,7 @@ namespace winsw
|
||||||
internal WinSWExtensionManager ExtensionManager { private set; get; }
|
internal WinSWExtensionManager ExtensionManager { private set; get; }
|
||||||
|
|
||||||
private static readonly ILog Log = LogManager.GetLogger("WinSW");
|
private static readonly ILog Log = LogManager.GetLogger("WinSW");
|
||||||
|
private static readonly WrapperServiceEventLogProvider eventLogProvider = new WrapperServiceEventLogProvider();
|
||||||
|
|
||||||
/// <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,
|
||||||
|
@ -53,6 +55,13 @@ namespace winsw
|
||||||
get { return Assembly.GetExecutingAssembly().GetName().Version; }
|
get { return Assembly.GetExecutingAssembly().GetName().Version; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the system is shutting down.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsShuttingDown {
|
||||||
|
get { return _systemShuttingdown; }
|
||||||
|
}
|
||||||
|
|
||||||
public WrapperService(ServiceDescriptor descriptor)
|
public WrapperService(ServiceDescriptor descriptor)
|
||||||
{
|
{
|
||||||
_descriptor = descriptor;
|
_descriptor = descriptor;
|
||||||
|
@ -63,6 +72,9 @@ namespace winsw
|
||||||
CanPauseAndContinue = false;
|
CanPauseAndContinue = false;
|
||||||
AutoLog = true;
|
AutoLog = true;
|
||||||
_systemShuttingdown = false;
|
_systemShuttingdown = false;
|
||||||
|
|
||||||
|
// Register the event log provider
|
||||||
|
eventLogProvider.service = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WrapperService() : this (new ServiceDescriptor())
|
public WrapperService() : this (new ServiceDescriptor())
|
||||||
|
@ -135,7 +147,7 @@ namespace winsw
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
WriteEvent("Thread failed unexpectedly",e);
|
Log.Error("Thread failed unexpectedly",e);
|
||||||
}
|
}
|
||||||
}).Start();
|
}).Start();
|
||||||
}
|
}
|
||||||
|
@ -171,7 +183,7 @@ namespace winsw
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
WriteEvent("Failed to log event in Windows Event Log: " + message + "; Reason: ", e);
|
Log.Error("Failed to log event in Windows Event Log: " + message + "; Reason: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,28 +202,11 @@ namespace winsw
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
WriteEvent("Failed to log event in Windows Event Log. Reason: ", e);
|
Log.Error("Failed to log event in Windows Event Log. Reason: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteEvent(Exception exception)
|
|
||||||
{
|
|
||||||
//TODO: pass exception to logger
|
|
||||||
WriteEvent(exception.Message + "\nStacktrace:" + exception.StackTrace, Level.Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteEvent(String message, Exception exception)
|
|
||||||
{
|
|
||||||
//TODO: pass exception to logger
|
|
||||||
WriteEvent(message + "\nMessage:" + exception.Message + "\nStacktrace:" + exception.StackTrace, Level.Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteEvent(String message, Level logLevel = null, Exception ex = null)
|
|
||||||
{
|
|
||||||
Log.Logger.Log(GetType(), logLevel ?? Level.Info, message, ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnStart(string[] _)
|
protected override void OnStart(string[] _)
|
||||||
{
|
{
|
||||||
_envs = _descriptor.EnvironmentVariables;
|
_envs = _descriptor.EnvironmentVariables;
|
||||||
|
@ -233,7 +228,7 @@ namespace winsw
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogEvent("Failed to download " + d.From + " to " + d.To + "\n" + e.Message);
|
LogEvent("Failed to download " + d.From + " to " + d.To + "\n" + e.Message);
|
||||||
WriteEvent("Failed to download " + d.From +" to "+d.To, e);
|
Log.Error("Failed to download " + d.From +" to "+d.To, e);
|
||||||
// but just keep going
|
// but just keep going
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,23 +245,14 @@ namespace winsw
|
||||||
}
|
}
|
||||||
|
|
||||||
LogEvent("Starting " + _descriptor.Executable + ' ' + startarguments);
|
LogEvent("Starting " + _descriptor.Executable + ' ' + startarguments);
|
||||||
WriteEvent("Starting " + _descriptor.Executable + ' ' + startarguments);
|
Log.Info("Starting " + _descriptor.Executable + ' ' + startarguments);
|
||||||
|
|
||||||
// Load and start extensions
|
// Load and start extensions
|
||||||
ExtensionManager.LoadExtensions(this);
|
ExtensionManager.LoadExtensions();
|
||||||
try
|
ExtensionManager.FireOnWrapperStarted();
|
||||||
{
|
|
||||||
ExtensionManager.OnStart(this);
|
|
||||||
}
|
|
||||||
catch (ExtensionException ex)
|
|
||||||
{
|
|
||||||
LogEvent("Failed to start extension " + ex.ExtensionId + "\n" + ex.Message, EventLogEntryType.Error);
|
|
||||||
WriteEvent("Failed to start extension " + ex.ExtensionId, ex);
|
|
||||||
//TODO: Exit on error?
|
|
||||||
}
|
|
||||||
|
|
||||||
LogEvent("Starting " + _descriptor.Executable + ' ' + startarguments);
|
LogEvent("Starting " + _descriptor.Executable + ' ' + startarguments);
|
||||||
WriteEvent("Starting " + _descriptor.Executable + ' ' + startarguments);
|
Log.Info("Starting " + _descriptor.Executable + ' ' + startarguments);
|
||||||
|
|
||||||
StartProcess(_process, startarguments, _descriptor.Executable);
|
StartProcess(_process, startarguments, _descriptor.Executable);
|
||||||
ExtensionManager.FireOnProcessStarted(_process);
|
ExtensionManager.FireOnProcessStarted(_process);
|
||||||
|
@ -288,7 +274,7 @@ namespace winsw
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
WriteEvent("Shutdown exception", ex);
|
Log.Error("Shutdown exception", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +288,7 @@ namespace winsw
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
WriteEvent("Stop exception", ex);
|
Log.Error("Cannot stop exception", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,14 +299,14 @@ namespace winsw
|
||||||
{
|
{
|
||||||
string stoparguments = _descriptor.Stoparguments;
|
string stoparguments = _descriptor.Stoparguments;
|
||||||
LogEvent("Stopping " + _descriptor.Id);
|
LogEvent("Stopping " + _descriptor.Id);
|
||||||
WriteEvent("Stopping " + _descriptor.Id);
|
Log.Info("Stopping " + _descriptor.Id);
|
||||||
_orderlyShutdown = true;
|
_orderlyShutdown = true;
|
||||||
|
|
||||||
if (stoparguments == null)
|
if (stoparguments == null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteEvent("ProcessKill " + _process.Id);
|
Log.Debug("ProcessKill " + _process.Id);
|
||||||
ProcessHelper.StopProcessAndChildren(_process.Id, _descriptor.StopTimeout, _descriptor.StopParentProcessFirst);
|
ProcessHelper.StopProcessAndChildren(_process.Id, _descriptor.StopTimeout, _descriptor.StopParentProcessFirst);
|
||||||
ExtensionManager.FireOnProcessTerminated(_process);
|
ExtensionManager.FireOnProcessTerminated(_process);
|
||||||
}
|
}
|
||||||
|
@ -345,29 +331,21 @@ namespace winsw
|
||||||
|
|
||||||
StartProcess(stopProcess, stoparguments, executable);
|
StartProcess(stopProcess, stoparguments, executable);
|
||||||
|
|
||||||
WriteEvent("WaitForProcessToExit "+_process.Id+"+"+stopProcess.Id);
|
Log.Debug("WaitForProcessToExit " + _process.Id + "+" + stopProcess.Id);
|
||||||
WaitForProcessToExit(_process);
|
WaitForProcessToExit(_process);
|
||||||
WaitForProcessToExit(stopProcess);
|
WaitForProcessToExit(stopProcess);
|
||||||
SignalShutdownComplete();
|
SignalShutdownComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop extensions
|
// Stop extensions
|
||||||
try
|
ExtensionManager.FireBeforeWrapperStopped();
|
||||||
{
|
|
||||||
ExtensionManager.OnStop(this);
|
|
||||||
}
|
|
||||||
catch (ExtensionException ex)
|
|
||||||
{
|
|
||||||
LogEvent("Failed to stop extension " + ex.ExtensionId + "\n" + ex.Message, EventLogEntryType.Error);
|
|
||||||
WriteEvent("Failed to stop extension " + ex.ExtensionId, ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_systemShuttingdown && _descriptor.BeepOnShutdown)
|
if (_systemShuttingdown && _descriptor.BeepOnShutdown)
|
||||||
{
|
{
|
||||||
Console.Beep();
|
Console.Beep();
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteEvent("Finished " + _descriptor.Id);
|
Log.Info("Finished " + _descriptor.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WaitForProcessToExit(Process processoWait)
|
private void WaitForProcessToExit(Process processoWait)
|
||||||
|
@ -458,7 +436,7 @@ namespace winsw
|
||||||
ps.EnvironmentVariables[WinSWSystem.ENVVAR_NAME_SERVICE_ID.ToLower()] = _descriptor.Id;
|
ps.EnvironmentVariables[WinSWSystem.ENVVAR_NAME_SERVICE_ID.ToLower()] = _descriptor.Id;
|
||||||
|
|
||||||
processToStart.Start();
|
processToStart.Start();
|
||||||
WriteEvent("Started " + processToStart.Id);
|
Log.Info("Started " + processToStart.Id);
|
||||||
|
|
||||||
var priority = _descriptor.Priority;
|
var priority = _descriptor.Priority;
|
||||||
if (priority != ProcessPriorityClass.Normal)
|
if (priority != ProcessPriorityClass.Normal)
|
||||||
|
@ -509,6 +487,7 @@ namespace winsw
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Run(args);
|
Run(args);
|
||||||
|
Log.Info("Completed. Exit code is 0");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch (WmiException e)
|
catch (WmiException e)
|
||||||
|
@ -554,7 +533,7 @@ namespace winsw
|
||||||
|
|
||||||
if (isCLIMode) // CLI mode, in-service mode otherwise
|
if (isCLIMode) // CLI mode, in-service mode otherwise
|
||||||
{
|
{
|
||||||
Log.Debug("Starting ServiceWrapper in CLI mode");
|
Log.Info("Starting ServiceWrapper in the CLI mode");
|
||||||
|
|
||||||
// Get service info for the future use
|
// Get service info for the future use
|
||||||
Win32Services svc = new WmiRoot().GetCollection<Win32Services>();
|
Win32Services svc = new WmiRoot().GetCollection<Win32Services>();
|
||||||
|
@ -761,17 +740,25 @@ namespace winsw
|
||||||
throw new Exception("Unknown command: " + args[0]);
|
throw new Exception("Unknown command: " + args[0]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Info("Starting ServiceWrapper in the service mode");
|
||||||
|
}
|
||||||
Run(new WrapperService());
|
Run(new WrapperService());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InitLoggers(ServiceDescriptor d, bool enableCLILogging)
|
private static void InitLoggers(ServiceDescriptor d, bool enableCLILogging)
|
||||||
{
|
{
|
||||||
|
// TODO: Make logging levels configurable
|
||||||
Level logLevel = Level.Debug;
|
Level logLevel = Level.Debug;
|
||||||
|
Level eventLogLevel = Level.Warn;
|
||||||
|
|
||||||
// Legacy format from winsw-1.x: (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " - " + message);
|
// Legacy format from winsw-1.x: (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " - " + message);
|
||||||
PatternLayout pl = new PatternLayout { ConversionPattern = "%d %-5p - %m%n" };
|
PatternLayout pl = new PatternLayout { ConversionPattern = "%d %-5p - %m%n" };
|
||||||
pl.ActivateOptions();
|
pl.ActivateOptions();
|
||||||
|
|
||||||
|
List<IAppender> appenders = new List<IAppender>();
|
||||||
|
|
||||||
// wrapper.log
|
// wrapper.log
|
||||||
String wrapperLogPath = Path.Combine(d.LogDirectory, d.BaseName + ".wrapper.log");
|
String wrapperLogPath = Path.Combine(d.LogDirectory, d.BaseName + ".wrapper.log");
|
||||||
var wrapperLog = new FileAppender
|
var wrapperLog = new FileAppender
|
||||||
|
@ -785,7 +772,7 @@ namespace winsw
|
||||||
Layout = pl
|
Layout = pl
|
||||||
};
|
};
|
||||||
wrapperLog.ActivateOptions();
|
wrapperLog.ActivateOptions();
|
||||||
BasicConfigurator.Configure(wrapperLog);
|
appenders.Add(wrapperLog);
|
||||||
|
|
||||||
// Also display logs in CLI if required
|
// Also display logs in CLI if required
|
||||||
if (enableCLILogging)
|
if (enableCLILogging)
|
||||||
|
@ -794,11 +781,23 @@ namespace winsw
|
||||||
{
|
{
|
||||||
Name = "Wrapper console log",
|
Name = "Wrapper console log",
|
||||||
Threshold = logLevel,
|
Threshold = logLevel,
|
||||||
Layout = pl
|
Layout = pl,
|
||||||
};
|
};
|
||||||
consoleAppender.ActivateOptions();
|
consoleAppender.ActivateOptions();
|
||||||
((Logger)Log.Logger).AddAppender(consoleAppender);
|
appenders.Add(consoleAppender);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// System log
|
||||||
|
var systemEventLogger = new ServiceEventLogAppender
|
||||||
|
{
|
||||||
|
Name = "System event log",
|
||||||
|
Threshold = eventLogLevel,
|
||||||
|
provider = eventLogProvider
|
||||||
|
};
|
||||||
|
systemEventLogger.ActivateOptions();
|
||||||
|
appenders.Add(systemEventLogger);
|
||||||
|
|
||||||
|
BasicConfigurator.Configure(appenders.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ReadPassword()
|
private static string ReadPassword()
|
||||||
|
|
|
@ -79,6 +79,7 @@
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="SigIntHelper.cs" />
|
<Compile Include="SigIntHelper.cs" />
|
||||||
|
<Compile Include="Logging\WrapperServiceEventLogProvider.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="manifest.xml" />
|
<Content Include="manifest.xml" />
|
||||||
|
|
|
@ -9,17 +9,17 @@ namespace winsw.Extensions
|
||||||
public abstract String DisplayName { get; }
|
public abstract String DisplayName { get; }
|
||||||
public WinSWExtensionDescriptor Descriptor { get; set; }
|
public WinSWExtensionDescriptor Descriptor { get; set; }
|
||||||
|
|
||||||
public virtual void Configure(ServiceDescriptor descriptor, XmlNode node, IEventWriter logger)
|
public virtual void Configure(ServiceDescriptor descriptor, XmlNode node)
|
||||||
{
|
{
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnStart(IEventWriter eventWriter)
|
public virtual void OnWrapperStarted()
|
||||||
{
|
{
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnStop(IEventWriter eventWriter)
|
public virtual void BeforeWrapperStopped()
|
||||||
{
|
{
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,14 +29,14 @@ namespace winsw.Extensions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="descriptor">Service descriptor</param>
|
/// <param name="descriptor">Service descriptor</param>
|
||||||
/// <param name="node">Configuration node</param>
|
/// <param name="node">Configuration node</param>
|
||||||
void Configure(ServiceDescriptor descriptor, XmlNode node, IEventWriter logger);
|
void Configure(ServiceDescriptor descriptor, XmlNode node);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start handler. Called during startup of the service before the child process.
|
/// Start handler. Called during startup of the service before the child process.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">Logger</param>
|
/// <param name="logger">Logger</param>
|
||||||
/// <exception cref="ExtensionException">Any error during execution</exception>
|
/// <exception cref="ExtensionException">Any error during execution</exception>
|
||||||
void OnStart(IEventWriter logger);
|
void OnWrapperStarted();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handler, which is being invoked once the child process is started.
|
/// Handler, which is being invoked once the child process is started.
|
||||||
|
@ -59,6 +59,6 @@ namespace winsw.Extensions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">Logger</param>
|
/// <param name="logger">Logger</param>
|
||||||
/// <exception cref="ExtensionException">Any error during execution</exception>
|
/// <exception cref="ExtensionException">Any error during execution</exception>
|
||||||
void OnStop(IEventWriter logger);
|
void BeforeWrapperStopped();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,26 +22,43 @@ namespace winsw.Extensions
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starts all extensions
|
/// Notifies all extensions that the wrapper is being started.
|
||||||
|
/// They are supposed to run the initialization logic.
|
||||||
|
/// If any extensions fails, WinSW startup should be interrupted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <exception cref="ExtensionException">Start failure</exception>
|
/// <exception cref="Exception">Start failure</exception>
|
||||||
public void OnStart(IEventWriter logger)
|
public void FireOnWrapperStarted()
|
||||||
{
|
{
|
||||||
foreach (var ext in Extensions)
|
foreach (var ext in Extensions)
|
||||||
{
|
{
|
||||||
ext.Value.OnStart(logger);
|
try
|
||||||
|
{
|
||||||
|
ext.Value.OnWrapperStarted();
|
||||||
|
}
|
||||||
|
catch (ExtensionException ex)
|
||||||
|
{
|
||||||
|
Log.Fatal("onWrapperStarted() handler failed for " + ext.Value.DisplayName, ex);
|
||||||
|
throw ex; // Propagate error to stop the startup
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stops all extensions
|
/// Notifies all extensions that the wrapper is being stopped.
|
||||||
|
/// If an error happens, further extensions will be tried
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <exception cref="ExtensionException">Stop failure</exception>
|
public void FireBeforeWrapperStopped()
|
||||||
public void OnStop(IEventWriter logger)
|
|
||||||
{
|
{
|
||||||
foreach (var ext in Extensions)
|
foreach (var ext in Extensions)
|
||||||
{
|
{
|
||||||
ext.Value.OnStop(logger);
|
try
|
||||||
|
{
|
||||||
|
ext.Value.BeforeWrapperStopped();
|
||||||
|
}
|
||||||
|
catch (ExtensionException ex)
|
||||||
|
{
|
||||||
|
Log.Error("beforeWrapperStopped() handler failed for " + ext.Value.DisplayName, ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,17 +103,17 @@ namespace winsw.Extensions
|
||||||
//TODO: Implement loading of external extensions. Current version supports internal hack
|
//TODO: Implement loading of external extensions. Current version supports internal hack
|
||||||
#region Extension load management
|
#region Extension load management
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Loads extensions according to the configuration file.
|
/// Loads extensions according to the configuration file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">Logger</param>
|
/// <param name="logger">Logger</param>
|
||||||
/// <exception cref="Exception">Loading failure</exception>
|
/// <exception cref="Exception">Loading failure</exception>
|
||||||
public void LoadExtensions(IEventWriter logger)
|
public void LoadExtensions()
|
||||||
{
|
{
|
||||||
var extensionIds = ServiceDescriptor.ExtensionIds;
|
var extensionIds = ServiceDescriptor.ExtensionIds;
|
||||||
foreach (String extensionId in extensionIds)
|
foreach (String extensionId in extensionIds)
|
||||||
{
|
{
|
||||||
LoadExtension(extensionId, logger);
|
LoadExtension(extensionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +123,7 @@ namespace winsw.Extensions
|
||||||
/// <param name="id">Extension ID</param>
|
/// <param name="id">Extension ID</param>
|
||||||
/// <param name="logger">Logger</param>
|
/// <param name="logger">Logger</param>
|
||||||
/// <exception cref="Exception">Loading failure</exception>
|
/// <exception cref="Exception">Loading failure</exception>
|
||||||
private void LoadExtension(string id, IEventWriter logger)
|
private void LoadExtension(string id)
|
||||||
{
|
{
|
||||||
if (Extensions.ContainsKey(id))
|
if (Extensions.ContainsKey(id))
|
||||||
{
|
{
|
||||||
|
@ -127,7 +144,7 @@ namespace winsw.Extensions
|
||||||
extension.Descriptor = descriptor;
|
extension.Descriptor = descriptor;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
extension.Configure(ServiceDescriptor, configNode, logger);
|
extension.Configure(ServiceDescriptor, configNode);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{ // Consider any unexpected exception as fatal
|
{ // Consider any unexpected exception as fatal
|
||||||
|
@ -135,11 +152,11 @@ namespace winsw.Extensions
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
Extensions.Add(id, extension);
|
Extensions.Add(id, extension);
|
||||||
logger.LogEvent("Extension loaded: "+id, EventLogEntryType.Information);
|
Log.Info("Extension loaded: " + id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logger.LogEvent("Extension is disabled: " + id, EventLogEntryType.Warning);
|
Log.Warn("Extension is disabled: " + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace winsw.Logging
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the class may reference the event log
|
||||||
|
/// </summary>
|
||||||
|
public interface IServiceEventLogProvider
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Locates Event Log for the service.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Event Log or null if it is not avilable</returns>
|
||||||
|
EventLog locate();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
using log4net.Appender;
|
||||||
|
using log4net.Core;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace winsw.Logging
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Implementes service Event log appender for log4j.
|
||||||
|
/// The implementation presumes that service gets initialized after the logging.
|
||||||
|
/// </summary>
|
||||||
|
public class ServiceEventLogAppender : AppenderSkeleton
|
||||||
|
{
|
||||||
|
public IServiceEventLogProvider provider { get; set; }
|
||||||
|
|
||||||
|
override protected void Append(LoggingEvent loggingEvent)
|
||||||
|
{
|
||||||
|
EventLog eventLog = provider.locate();
|
||||||
|
if (eventLog != null)
|
||||||
|
{
|
||||||
|
// We write the event iff the provider is ready
|
||||||
|
eventLog.WriteEntry(loggingEvent.RenderedMessage, toEventLogEntryType(loggingEvent.Level));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EventLogEntryType toEventLogEntryType(Level level)
|
||||||
|
{
|
||||||
|
if (level.Value >= Level.Error.Value)
|
||||||
|
{
|
||||||
|
return EventLogEntryType.Error;
|
||||||
|
}
|
||||||
|
if (level.Value >= Level.Warn.Value)
|
||||||
|
{
|
||||||
|
return EventLogEntryType.Warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All other events will be posted as information
|
||||||
|
return EventLogEntryType.Information;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace winsw.Util
|
|
||||||
{
|
|
||||||
public interface IEventWriter
|
|
||||||
{
|
|
||||||
void LogEvent(String message);
|
|
||||||
void LogEvent(String message, EventLogEntryType type);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -54,12 +54,13 @@
|
||||||
<Compile Include="Extensions\WinSWExtensionDescriptor.cs" />
|
<Compile Include="Extensions\WinSWExtensionDescriptor.cs" />
|
||||||
<Compile Include="Extensions\WinSWExtensionManager.cs" />
|
<Compile Include="Extensions\WinSWExtensionManager.cs" />
|
||||||
<Compile Include="LogAppenders.cs" />
|
<Compile Include="LogAppenders.cs" />
|
||||||
|
<Compile Include="Logging\ServiceEventLogAppender.cs" />
|
||||||
|
<Compile Include="Logging\IServiceEventLogProvider.cs" />
|
||||||
<Compile Include="Native\Advapi32.cs" />
|
<Compile Include="Native\Advapi32.cs" />
|
||||||
<Compile Include="Native\Kernel32.cs" />
|
<Compile Include="Native\Kernel32.cs" />
|
||||||
<Compile Include="PeriodicRollingCalendar.cs" />
|
<Compile Include="PeriodicRollingCalendar.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="ServiceDescriptor.cs" />
|
<Compile Include="ServiceDescriptor.cs" />
|
||||||
<Compile Include="Util\IEventWriter.cs" />
|
|
||||||
<Compile Include="Util\ProcessHelper.cs" />
|
<Compile Include="Util\ProcessHelper.cs" />
|
||||||
<Compile Include="Util\SigIntHelper.cs" />
|
<Compile Include="Util\SigIntHelper.cs" />
|
||||||
<Compile Include="Util\XmlHelper.cs" />
|
<Compile Include="Util\XmlHelper.cs" />
|
||||||
|
@ -71,6 +72,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace winsw.Plugins.RunawayProcessKiller
|
||||||
this.Pidfile = pidfile;
|
this.Pidfile = pidfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Configure(ServiceDescriptor descriptor, XmlNode node, IEventWriter logger)
|
public override void Configure(ServiceDescriptor descriptor, XmlNode node)
|
||||||
{
|
{
|
||||||
// We expect the upper logic to process any errors
|
// We expect the upper logic to process any errors
|
||||||
// TODO: a better parser API for types would be useful
|
// TODO: a better parser API for types would be useful
|
||||||
|
@ -57,7 +57,7 @@ namespace winsw.Plugins.RunawayProcessKiller
|
||||||
/// This method checks if the PID file is stored on the disk and then terminates runaway processes if they exist.
|
/// This method checks if the PID file is stored on the disk and then terminates runaway processes if they exist.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">Unused logger</param>
|
/// <param name="logger">Unused logger</param>
|
||||||
public override void OnStart(IEventWriter logger)
|
public override void OnWrapperStarted()
|
||||||
{
|
{
|
||||||
// Read PID file from the disk
|
// Read PID file from the disk
|
||||||
int pid;
|
int pid;
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Xml;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using winsw.Extensions;
|
using winsw.Extensions;
|
||||||
using winsw.Util;
|
using winsw.Util;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
namespace winsw.Plugins.SharedDirectoryMapper
|
namespace winsw.Plugins.SharedDirectoryMapper
|
||||||
{
|
{
|
||||||
|
@ -14,6 +15,8 @@ namespace winsw.Plugins.SharedDirectoryMapper
|
||||||
|
|
||||||
public override String DisplayName { get { return "Shared Directory Mapper"; } }
|
public override String DisplayName { get { return "Shared Directory Mapper"; } }
|
||||||
|
|
||||||
|
private static readonly ILog Logger = LogManager.GetLogger(typeof(SharedDirectoryMapper));
|
||||||
|
|
||||||
public SharedDirectoryMapper()
|
public SharedDirectoryMapper()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -24,7 +27,7 @@ namespace winsw.Plugins.SharedDirectoryMapper
|
||||||
_entries.Add(config);
|
_entries.Add(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Configure(ServiceDescriptor descriptor, XmlNode node, IEventWriter logger)
|
public override void Configure(ServiceDescriptor descriptor, XmlNode node)
|
||||||
{
|
{
|
||||||
var nodes = XmlHelper.SingleNode(node, "mapping", false).SelectNodes("map");
|
var nodes = XmlHelper.SingleNode(node, "mapping", false).SelectNodes("map");
|
||||||
if (nodes != null)
|
if (nodes != null)
|
||||||
|
@ -41,30 +44,30 @@ namespace winsw.Plugins.SharedDirectoryMapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnStart(IEventWriter eventWriter)
|
public override void OnWrapperStarted()
|
||||||
{
|
{
|
||||||
foreach (SharedDirectoryMapperConfig config in _entries)
|
foreach (SharedDirectoryMapperConfig config in _entries)
|
||||||
{
|
{
|
||||||
if (config.EnableMapping)
|
if (config.EnableMapping)
|
||||||
{
|
{
|
||||||
eventWriter.LogEvent(DisplayName + ": Mapping shared directory " + config.UNCPath + " to " + config.Label, EventLogEntryType.Information);
|
Logger.Info(DisplayName + ": Mapping shared directory " + config.UNCPath + " to " + config.Label);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_mapper.MapDirectory(config.Label, config.UNCPath);
|
_mapper.MapDirectory(config.Label, config.UNCPath);
|
||||||
}
|
}
|
||||||
catch (MapperException ex)
|
catch (MapperException ex)
|
||||||
{
|
{
|
||||||
HandleMappingError(config, eventWriter, ex);
|
HandleMappingError(config, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eventWriter.LogEvent(DisplayName + ": Mapping of " + config.Label + " is disabled", EventLogEntryType.Warning);
|
Logger.Warn(DisplayName + ": Mapping of " + config.Label + " is disabled");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnStop(IEventWriter eventWriter)
|
public override void BeforeWrapperStopped()
|
||||||
{
|
{
|
||||||
foreach (SharedDirectoryMapperConfig config in _entries)
|
foreach (SharedDirectoryMapperConfig config in _entries)
|
||||||
{
|
{
|
||||||
|
@ -76,18 +79,16 @@ namespace winsw.Plugins.SharedDirectoryMapper
|
||||||
}
|
}
|
||||||
catch (MapperException ex)
|
catch (MapperException ex)
|
||||||
{
|
{
|
||||||
HandleMappingError(config, eventWriter, ex);
|
HandleMappingError(config, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleMappingError(SharedDirectoryMapperConfig config, IEventWriter eventWriter, MapperException ex) {
|
private void HandleMappingError(SharedDirectoryMapperConfig config, MapperException ex) {
|
||||||
String prefix = "Mapping of " + config.Label+ " ";
|
Logger.Error("Mapping of " + config.Label + " failed. STDOUT: " + ex.Process.StandardOutput.ReadToEnd()
|
||||||
eventWriter.LogEvent(prefix + "STDOUT: " + ex.Process.StandardOutput.ReadToEnd(), EventLogEntryType.Information);
|
+ " \r\nSTDERR: " + ex.Process.StandardError.ReadToEnd(), ex);
|
||||||
eventWriter.LogEvent(prefix + "STDERR: " + ex.Process.StandardError.ReadToEnd(), EventLogEntryType.Information);
|
throw new ExtensionException(Descriptor.Id, DisplayName + ": Mapping of " + config.Label + "failed", ex);
|
||||||
|
|
||||||
throw new ExtensionException(Descriptor.Id, DisplayName + ": " + prefix + "failed", ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
<AssemblyName>SharedDirectoryMapper</AssemblyName>
|
<AssemblyName>SharedDirectoryMapper</AssemblyName>
|
||||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
|
||||||
|
<RestorePackages>true</RestorePackages>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
@ -34,6 +36,9 @@
|
||||||
<AssemblyOriginatorKeyFile>$(SolutionDir)..\winsw_key.snk</AssemblyOriginatorKeyFile>
|
<AssemblyOriginatorKeyFile>$(SolutionDir)..\winsw_key.snk</AssemblyOriginatorKeyFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="log4net">
|
||||||
|
<HintPath>..\..\packages\log4net.2.0.3\lib\net20-full\log4net.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
|
@ -50,7 +55,17 @@
|
||||||
<Name>WinSWCore</Name>
|
<Name>WinSWCore</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
|
||||||
|
</Target>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="log4net" version="2.0.3" targetFramework="net20" />
|
||||||
|
</packages>
|
|
@ -2,7 +2,6 @@
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using winsw.Extensions;
|
using winsw.Extensions;
|
||||||
using winsw.Plugins.SharedDirectoryMapper;
|
using winsw.Plugins.SharedDirectoryMapper;
|
||||||
using winswTests.util;
|
|
||||||
using winsw.Plugins.RunawayProcessKiller;
|
using winsw.Plugins.RunawayProcessKiller;
|
||||||
|
|
||||||
namespace winswTests.Extensions
|
namespace winswTests.Extensions
|
||||||
|
@ -11,7 +10,6 @@ namespace winswTests.Extensions
|
||||||
class RunawayProcessKillerExtensionTest : ExtensionTestBase
|
class RunawayProcessKillerExtensionTest : ExtensionTestBase
|
||||||
{
|
{
|
||||||
ServiceDescriptor _testServiceDescriptor;
|
ServiceDescriptor _testServiceDescriptor;
|
||||||
readonly TestLogger _logger = new TestLogger();
|
|
||||||
|
|
||||||
string testExtension = getExtensionClassNameWithAssembly(typeof(RunawayProcessKillerExtension));
|
string testExtension = getExtensionClassNameWithAssembly(typeof(RunawayProcessKillerExtension));
|
||||||
|
|
||||||
|
@ -41,7 +39,7 @@ namespace winswTests.Extensions
|
||||||
public void LoadExtensions()
|
public void LoadExtensions()
|
||||||
{
|
{
|
||||||
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
|
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
|
||||||
manager.LoadExtensions(_logger);
|
manager.LoadExtensions();
|
||||||
Assert.AreEqual(1, manager.Extensions.Count, "One extension should be loaded");
|
Assert.AreEqual(1, manager.Extensions.Count, "One extension should be loaded");
|
||||||
|
|
||||||
// Check the file is correct
|
// Check the file is correct
|
||||||
|
@ -56,9 +54,9 @@ namespace winswTests.Extensions
|
||||||
public void StartStopExtension()
|
public void StartStopExtension()
|
||||||
{
|
{
|
||||||
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
|
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
|
||||||
manager.LoadExtensions(_logger);
|
manager.LoadExtensions();
|
||||||
manager.OnStart(_logger);
|
manager.FireOnWrapperStarted();
|
||||||
manager.OnStop(_logger);
|
manager.FireBeforeWrapperStopped();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using winsw.Extensions;
|
using winsw.Extensions;
|
||||||
using winsw.Plugins.SharedDirectoryMapper;
|
using winsw.Plugins.SharedDirectoryMapper;
|
||||||
using winswTests.util;
|
|
||||||
|
|
||||||
namespace winswTests.Extensions
|
namespace winswTests.Extensions
|
||||||
{
|
{
|
||||||
|
@ -10,7 +9,6 @@ namespace winswTests.Extensions
|
||||||
class SharedDirectoryMapperTest : ExtensionTestBase
|
class SharedDirectoryMapperTest : ExtensionTestBase
|
||||||
{
|
{
|
||||||
ServiceDescriptor _testServiceDescriptor;
|
ServiceDescriptor _testServiceDescriptor;
|
||||||
readonly TestLogger _logger = new TestLogger();
|
|
||||||
|
|
||||||
string testExtension = getExtensionClassNameWithAssembly(typeof(SharedDirectoryMapper));
|
string testExtension = getExtensionClassNameWithAssembly(typeof(SharedDirectoryMapper));
|
||||||
|
|
||||||
|
@ -48,7 +46,7 @@ namespace winswTests.Extensions
|
||||||
public void LoadExtensions()
|
public void LoadExtensions()
|
||||||
{
|
{
|
||||||
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
|
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
|
||||||
manager.LoadExtensions(_logger);
|
manager.LoadExtensions();
|
||||||
Assert.AreEqual(2, manager.Extensions.Count, "Two extensions should be loaded");
|
Assert.AreEqual(2, manager.Extensions.Count, "Two extensions should be loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,9 +54,9 @@ namespace winswTests.Extensions
|
||||||
public void StartStopExtension()
|
public void StartStopExtension()
|
||||||
{
|
{
|
||||||
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
|
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
|
||||||
manager.LoadExtensions(_logger);
|
manager.LoadExtensions();
|
||||||
manager.OnStart(_logger);
|
manager.FireOnWrapperStarted();
|
||||||
manager.OnStop(_logger);
|
manager.FireBeforeWrapperStopped();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using winsw.Util;
|
|
||||||
|
|
||||||
namespace winswTests.util
|
|
||||||
{
|
|
||||||
class TestLogger : IEventWriter
|
|
||||||
{
|
|
||||||
public void LogEvent(String message)
|
|
||||||
{
|
|
||||||
Console.WriteLine(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LogEvent(String message, EventLogEntryType type)
|
|
||||||
{
|
|
||||||
Console.WriteLine("[" + type + "]" + message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -61,7 +61,6 @@
|
||||||
<Compile Include="MainTest.cs" />
|
<Compile Include="MainTest.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="ServiceDescriptorTests.cs" />
|
<Compile Include="ServiceDescriptorTests.cs" />
|
||||||
<Compile Include="Util\TestLogger.cs" />
|
|
||||||
<Compile Include="Util\CLITestHelper.cs" />
|
<Compile Include="Util\CLITestHelper.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -3,5 +3,6 @@
|
||||||
<repository path="..\Core\ServiceWrapper\packages.config" />
|
<repository path="..\Core\ServiceWrapper\packages.config" />
|
||||||
<repository path="..\Core\WinSWCore\packages.config" />
|
<repository path="..\Core\WinSWCore\packages.config" />
|
||||||
<repository path="..\Plugins\RunawayProcessKiller\packages.config" />
|
<repository path="..\Plugins\RunawayProcessKiller\packages.config" />
|
||||||
|
<repository path="..\Plugins\SharedDirectoryMapper\packages.config" />
|
||||||
<repository path="..\Test\winswTests\packages.config" />
|
<repository path="..\Test\winswTests\packages.config" />
|
||||||
</repositories>
|
</repositories>
|
Loading…
Reference in New Issue