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.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) { try { GlobalExceptionHandlers.Register(); IgnoreCertErrorPolicy.Register(); Logger.Info("Starting NzbDrone Console. Version {0}", Assembly.GetExecutingAssembly().GetName().Version); if (!PlatformValidation.IsValidate(userAlert)) { throw new TerminateApplicationException("Missing system requirements"); } _container = MainAppContainerBuilder.BuildContainer(startupContext); var appMode = GetApplicationMode(startupContext); Start(appMode); if (startCallback != null) { startCallback(_container); } SpinToExit(appMode); } catch (TerminateApplicationException e) { Logger.Info("Application has been terminated. Reason " + e.Reason); } } private static void Start(ApplicationModes applicationModes) { if (!IsInUtilityMode(applicationModes)) { EnsureSingleInstance(); } DbFactory.RegisterDatabase(_container); _container.Resolve().Route(applicationModes); } private static void SpinToExit(ApplicationModes applicationModes) { if (IsInUtilityMode(applicationModes)) { return; } var serviceFactory = _container.Resolve(); while (!serviceFactory.IsServiceStopped) { Thread.Sleep(1000); } } private static void EnsureSingleInstance() { _container.Resolve().EnforceSingleInstance(); } private static ApplicationModes GetApplicationMode(StartupContext startupContext) { if (startupContext.Flags.Contains(StartupContext.HELP)) { return ApplicationModes.Help; } if (!OsInfo.IsLinux && startupContext.InstallService) { return ApplicationModes.InstallService; } if (!OsInfo.IsLinux && 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; } } } } }