using System; using System.Reflection; using System.Threading; using NLog; using NzbDrone.Common.Composition; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Instrumentation; using NzbDrone.Common.Processes; using NzbDrone.Common.Security; using NzbDrone.Core.Datastore; namespace NzbDrone.Host { public static class Bootstrap { private static IContainer _container; private static readonly Logger Logger = NzbDroneLogger.GetLogger(); public static void Start(StartupContext startupContext, IUserAlert userAlert, Action startCallback = null) { LogTargets.Register(startupContext, false, true); try { GlobalExceptionHandlers.Register(); X509CertificateValidationPolicy.Register(); Logger.Info("Starting NzbDrone - {0} - Version {1}", Assembly.GetCallingAssembly().Location, Assembly.GetExecutingAssembly().GetName().Version); if (!PlatformValidation.IsValidate(userAlert)) { throw new TerminateApplicationException("Missing system requirements"); } _container = MainAppContainerBuilder.BuildContainer(startupContext); _container.Resolve().Register(); _container.Resolve().Write(); var appMode = GetApplicationMode(startupContext); Start(appMode, startupContext); if (startCallback != null) { startCallback(_container); } else { SpinToExit(appMode); } } catch (TerminateApplicationException e) { Logger.Info(e.Message); LogManager.Configuration = null; } } private static void Start(ApplicationModes applicationModes, StartupContext startupContext) { if (!IsInUtilityMode(applicationModes)) { if (startupContext.Flags.Contains(StartupContext.RESTART)) { Thread.Sleep(2000); } EnsureSingleInstance(applicationModes == ApplicationModes.Service, startupContext); } DbFactory.RegisterDatabase(_container); _container.Resolve().Route(applicationModes); } private static void SpinToExit(ApplicationModes applicationModes) { if (IsInUtilityMode(applicationModes)) { return; } _container.Resolve().Spin(); } private static void EnsureSingleInstance(bool isService, IStartupContext startupContext) { var instancePolicy = _container.Resolve(); if (isService) { instancePolicy.KillAllOtherInstance(); } else if (startupContext.Flags.Contains(StartupContext.TERMINATE)) { instancePolicy.KillAllOtherInstance(); } else { instancePolicy.PreventStartIfAlreadyRunning(); } } private static ApplicationModes GetApplicationMode(IStartupContext startupContext) { if (startupContext.Flags.Contains(StartupContext.HELP)) { return ApplicationModes.Help; } if (!OsInfo.IsMono && startupContext.InstallService) { return ApplicationModes.InstallService; } if (!OsInfo.IsMono && startupContext.UninstallService) { return ApplicationModes.UninstallService; } if (_container.Resolve().IsWindowsService) { return ApplicationModes.Service; } return ApplicationModes.Interactive; } private static bool IsInUtilityMode(ApplicationModes applicationMode) { switch (applicationMode) { case ApplicationModes.InstallService: case ApplicationModes.UninstallService: case ApplicationModes.Help: { return true; } default: { return false; } } } } }