using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
using ZeroLevel.Services.Applications;
namespace ZeroLevel
{
public class Bootstrap
{
static Bootstrap()
{
// Tricks for minimize config changes for dependency resolve
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
try
{
Log.Debug($"[Bootstrap] Resolve assembly '{args.Name}'");
if (args.Name.StartsWith("Newtonsoft.Json", StringComparison.Ordinal))
{
return Assembly.LoadFile(Path.Combine(Configuration.BaseDirectory, "Newtonsoft.Json.dll"));
}
else if (args.Name.Equals("Microsoft.Owin", StringComparison.Ordinal))
{
return Assembly.LoadFile(Path.Combine(Configuration.BaseDirectory, "Microsoft.Owin.dll"));
}
var candidates = Directory.GetFiles(Path.Combine(Configuration.BaseDirectory), args.Name, SearchOption.TopDirectoryOnly);
if (candidates != null && candidates.Any())
{
return Assembly.LoadFile(candidates.First());
}
}
catch (Exception ex)
{
Log.Error(ex, $"[Bootstrap] Fault load assembly '{args.Name}'");
}
return null;
}
///
/// Self-install as windows service
///
private static void InstallApplication()
{
try
{
Configuration.Save(Configuration.ReadFromApplicationConfig());
Log.AddTextFileLogger("install.log");
BasicServiceInstaller.Install(Configuration.Default);
}
catch (Exception ex)
{
Log.Fatal(ex, "[Bootstrap] Fault service install");
}
}
///
/// Uninstall from windows services
///
private static void UninstallApplication()
{
try
{
Configuration.Save(Configuration.ReadFromApplicationConfig());
Log.AddTextFileLogger("uninstall.log");
BasicServiceInstaller.Uninstall(Configuration.Default);
}
catch (Exception ex)
{
Log.Fatal(ex, "[Bootstrap] Fault service uninstall");
}
}
public static void Startup(string[] args, Func preStartConfiguration = null, Func postStartConfiguration = null)
where T : IZeroService, new()
{
var cmd = Configuration.ReadFromCommandLine(args);
if (cmd.Contains("install", "setup"))
{
InstallApplication();
}
else if (cmd.Contains("uninstall", "remove"))
{
UninstallApplication();
}
else
{
Configuration.Save(Configuration.ReadFromApplicationConfig());
Log.CreateLoggingFromConfiguration(Configuration.Default);
IZeroService service = null;
if (preStartConfiguration != null)
{
try
{
if (preStartConfiguration() == false)
{
Log.SystemInfo("[Bootstrap] Service start canceled, because custom preconfig return false");
return;
}
}
catch (Exception ex)
{
Log.SystemError(ex, "[Bootstrap] Service start canceled, preconfig faulted");
return;
}
}
try
{
service = new T();
}
catch (Exception ex)
{
Log.SystemError(ex, "[Bootstrap] Service start canceled, service constructor call fault");
}
if (postStartConfiguration != null)
{
try
{
if (postStartConfiguration() == false)
{
Log.SystemInfo("[Bootstrap] Service start canceled, because custom postconfig return false");
return;
}
}
catch (Exception ex)
{
Log.SystemError(ex, "[Bootstrap] Service start canceled, postconfig faulted");
return;
}
}
if (Environment.UserInteractive)
{
try
{
Log.Debug("[Bootstrap] The service starting (interactive mode)");
service?.InteractiveStart(args);
Log.Debug("[Bootstrap] The service stopped (interactive mode)");
}
catch (Exception ex)
{
Log.Fatal(ex, "[Bootstrap] The service start in interactive mode was faulted with error");
}
}
else
{
try
{
Log.Debug("[Bootstrap] The service starting (windows service)");
ServiceBase.Run(new ServiceBase[] { service as ServiceBase });
Log.Debug("[Bootstrap] The service stopped (windows service)");
}
catch (Exception ex)
{
Log.Fatal(ex, "[Bootstrap] The service start was faulted with error");
}
}
}
try { Sheduller.Dispose(); } catch { }
try { Log.Dispose(); } catch { }
try { Injector.Default.Dispose(); Injector.Dispose(); } catch { }
}
}
}