diff --git a/NzbDrone.App.Test/RouterTest.cs b/NzbDrone.App.Test/RouterTest.cs index e4f45028b..264277990 100644 --- a/NzbDrone.App.Test/RouterTest.cs +++ b/NzbDrone.App.Test/RouterTest.cs @@ -1,4 +1,5 @@ -using AutoMoq; +using System.ServiceProcess; +using AutoMoq; using FluentAssertions; using Moq; using NUnit.Framework; @@ -47,20 +48,23 @@ namespace NzbDrone.App.Test var mocker = new AutoMoqer(MockBehavior.Strict); var serviceProviderMock = mocker.GetMock(); serviceProviderMock.Setup(c => c.Install()); - mocker.GetMock().SetupGet(c => c.IsRunningAsService).Returns(false); + serviceProviderMock.Setup(c => c.ServiceExist(ServiceProvider.NzbDroneServiceName)).Returns(false); + mocker.GetMock().SetupGet(c => c.IsUserInteractive).Returns(true); mocker.Resolve().Route(ApplicationMode.InstallService); serviceProviderMock.Verify(c => c.Install(), Times.Once()); } + [Test] public void Route_should_call_uninstall_service_when_application_mode_is_uninstall() { var mocker = new AutoMoqer(MockBehavior.Strict); var serviceProviderMock = mocker.GetMock(); serviceProviderMock.Setup(c => c.UnInstall()); - mocker.GetMock().SetupGet(c => c.IsRunningAsService).Returns(false); + mocker.GetMock().SetupGet(c => c.IsUserInteractive).Returns(true); + serviceProviderMock.Setup(c => c.ServiceExist(ServiceProvider.NzbDroneServiceName)).Returns(true); mocker.Resolve().Route(ApplicationMode.UninstallService); @@ -75,7 +79,7 @@ namespace NzbDrone.App.Test var appServerProvider = mocker.GetMock(); consoleProvider.Setup(c => c.WaitForClose()); appServerProvider.Setup(c => c.Start()); - mocker.GetMock().SetupGet(c => c.IsRunningAsService).Returns(false); + mocker.GetMock().SetupGet(c => c.IsUserInteractive).Returns(true); mocker.Resolve().Route(ApplicationMode.Console); @@ -91,14 +95,15 @@ namespace NzbDrone.App.Test { var mocker = new AutoMoqer(MockBehavior.Strict); var envMock = mocker.GetMock(); - var appServerMock = mocker.GetMock(); + var serviceProvider = mocker.GetMock(); - envMock.SetupGet(c => c.IsRunningAsService).Returns(true); - appServerMock.Setup(c => c.StartService()); + envMock.SetupGet(c => c.IsUserInteractive).Returns(false); + + serviceProvider.Setup(c => c.Run(It.IsAny())); mocker.Resolve().Route(applicationMode); - appServerMock.Verify(c => c.StartService(), Times.Once()); + serviceProvider.Verify(c => c.Run(It.IsAny()), Times.Once()); } @@ -108,7 +113,7 @@ namespace NzbDrone.App.Test var mocker = new AutoMoqer(MockBehavior.Strict); var consoleMock = mocker.GetMock(); var serviceMock = mocker.GetMock(); - mocker.GetMock().SetupGet(c => c.IsRunningAsService).Returns(false); + mocker.GetMock().SetupGet(c => c.IsUserInteractive).Returns(true); consoleMock.Setup(c => c.PrintServiceAlreadyExist()); serviceMock.Setup(c => c.ServiceExist(ServiceProvider.NzbDroneServiceName)).Returns(true); @@ -117,5 +122,21 @@ namespace NzbDrone.App.Test mocker.VerifyAllMocks(); } + + [Test] + public void show_error_on_uninstall_if_service_doesnt_exist() + { + var mocker = new AutoMoqer(MockBehavior.Strict); + var consoleMock = mocker.GetMock(); + var serviceMock = mocker.GetMock(); + mocker.GetMock().SetupGet(c => c.IsUserInteractive).Returns(true); + + consoleMock.Setup(c => c.PrintServiceDoestExist()); + serviceMock.Setup(c => c.ServiceExist(ServiceProvider.NzbDroneServiceName)).Returns(false); + + mocker.Resolve().Route(ApplicationMode.UninstallService); + + mocker.VerifyAllMocks(); + } } } diff --git a/NzbDrone.App.Test/ServiceControllerTests.cs b/NzbDrone.App.Test/ServiceControllerTests.cs index 00534788d..05cab1154 100644 --- a/NzbDrone.App.Test/ServiceControllerTests.cs +++ b/NzbDrone.App.Test/ServiceControllerTests.cs @@ -40,7 +40,7 @@ namespace NzbDrone.App.Test var serviceController = new ServiceProvider(); //Act - serviceController.ServiceExist(ServiceProvider.NzbDroneServiceName).Should().BeFalse(); + serviceController.ServiceExist(ServiceProvider.NzbDroneServiceName).Should().BeFalse("Service already installed"); serviceController.Install(); serviceController.ServiceExist(ServiceProvider.NzbDroneServiceName).Should().BeTrue(); serviceController.UnInstall(); diff --git a/NzbDrone.Web/log.config b/NzbDrone.Web/log.config index 3e9e0b3a6..e1a578687 100644 --- a/NzbDrone.Web/log.config +++ b/NzbDrone.Web/log.config @@ -1,6 +1,6 @@  - + diff --git a/NzbDrone/ApplicationServer.cs b/NzbDrone/ApplicationServer.cs index f3f1c6bda..8cb093b15 100644 --- a/NzbDrone/ApplicationServer.cs +++ b/NzbDrone/ApplicationServer.cs @@ -1,5 +1,7 @@ using System; +using System.Diagnostics; using System.Net; +using System.Reflection; using System.ServiceProcess; using System.Threading; using NLog; @@ -17,19 +19,13 @@ namespace NzbDrone private readonly EnviromentProvider _enviromentProvider; private readonly IISProvider _iisProvider; private readonly ProcessProvider _processProvider; + private readonly MonitoringProvider _monitoringProvider; private readonly WebClient _webClient; - public void IsRunningAsService() - { - Logger.Warn(base.Container); - Logger.Warn(base.ServiceName); - - } - [Inject] public ApplicationServer(ConfigProvider configProvider, WebClient webClient, IISProvider iisProvider, DebuggerProvider debuggerProvider, EnviromentProvider enviromentProvider, - ProcessProvider processProvider) + ProcessProvider processProvider, MonitoringProvider monitoringProvider) { _configProvider = configProvider; _webClient = webClient; @@ -37,6 +33,7 @@ namespace NzbDrone _debuggerProvider = debuggerProvider; _enviromentProvider = enviromentProvider; _processProvider = processProvider; + _monitoringProvider = monitoringProvider; } public ApplicationServer() @@ -44,10 +41,9 @@ namespace NzbDrone } - public virtual void StartService() + protected override void OnStart(string[] args) { Start(); - Run(this); } public virtual void Start() @@ -80,14 +76,11 @@ namespace NzbDrone Logger.ErrorException("Failed to load home page.", e); } } - } - protected override void OnStop() - { - StopServer(); + _monitoringProvider.Start(); } - public void StopServer() + protected override void OnStop() { Logger.Info("Attempting to stop application."); _iisProvider.StopServer(); diff --git a/NzbDrone/CentralDispatch.cs b/NzbDrone/CentralDispatch.cs index 21513e626..6c4944f4e 100644 --- a/NzbDrone/CentralDispatch.cs +++ b/NzbDrone/CentralDispatch.cs @@ -50,7 +50,7 @@ namespace NzbDrone { _kernel.Get().ConfigureNlog(); _kernel.Get().CreateDefaultConfigFile(); - Logger.Info("Starting NZBDrone. Start-up Path:'{0}'", _kernel.Get().ApplicationPath); + Logger.Info("Start-up Path:'{0}'", _kernel.Get().ApplicationPath); Thread.CurrentThread.Name = "Host"; } } diff --git a/NzbDrone/Providers/ConsoleProvider.cs b/NzbDrone/Providers/ConsoleProvider.cs index c4374363b..e2281e905 100644 --- a/NzbDrone/Providers/ConsoleProvider.cs +++ b/NzbDrone/Providers/ConsoleProvider.cs @@ -1,12 +1,12 @@ using System; +using System.Diagnostics; +using System.Reflection; using NLog; namespace NzbDrone.Providers { public class ConsoleProvider { - private static readonly Logger Logger = LogManager.GetLogger("Host.ConsoleProvider"); - public virtual void WaitForClose() { while (true) @@ -17,13 +17,22 @@ namespace NzbDrone.Providers public virtual void PrintHelp() { - Logger.Info("Printing Help"); - Console.WriteLine("Help"); + Console.WriteLine(); + Console.WriteLine(" Usage: {0} ", Process.GetCurrentProcess().MainModule.ModuleName); + Console.WriteLine(" Commands:"); + Console.WriteLine(" /i Install the application as a Windows Service ({0}).", ServiceProvider.NzbDroneServiceName); + Console.WriteLine(" /u Uninstall already installed Windows Service ({0}).", ServiceProvider.NzbDroneServiceName); + Console.WriteLine(" Run application in console mode."); } public virtual void PrintServiceAlreadyExist() { Console.WriteLine("A service with the same name ({0}) already exists. Aborting installation", ServiceProvider.NzbDroneServiceName); } + + public virtual void PrintServiceDoestExist() + { + Console.WriteLine("Can't find service ({0})", ServiceProvider.NzbDroneServiceName); + } } } \ No newline at end of file diff --git a/NzbDrone/Providers/EnviromentProvider.cs b/NzbDrone/Providers/EnviromentProvider.cs index b12fff7b3..3373d37ae 100644 --- a/NzbDrone/Providers/EnviromentProvider.cs +++ b/NzbDrone/Providers/EnviromentProvider.cs @@ -16,37 +16,23 @@ namespace NzbDrone.Providers get { return Environment.UserInteractive; } } - public virtual bool IsRunningAsService - { - get - { - try - { - Console.Write(""); - return false; - } - catch (Exception) - { - return true; - } - } - } - public virtual string ApplicationPath { get { var dir = new FileInfo(Environment.CurrentDirectory).Directory; - while (dir.GetDirectories("iisexpress").Length == 0) + while (!ContainsIIS(dir)) { if (dir.Parent == null) break; dir = dir.Parent; } + if (ContainsIIS(dir)) return dir.FullName; + dir = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory; - while (dir.GetDirectories("iisexpress").Length == 0) + while (!ContainsIIS(dir)) { if (dir.Parent == null) throw new ApplicationException("Can't fine IISExpress folder."); dir = dir.Parent; @@ -55,5 +41,10 @@ namespace NzbDrone.Providers return dir.FullName; } } + + private static bool ContainsIIS(DirectoryInfo dir) + { + return dir.GetDirectories("iisexpress").Length != 0; + } } } \ No newline at end of file diff --git a/NzbDrone/Providers/ServiceProvider.cs b/NzbDrone/Providers/ServiceProvider.cs index 99c00140d..8667b28ad 100644 --- a/NzbDrone/Providers/ServiceProvider.cs +++ b/NzbDrone/Providers/ServiceProvider.cs @@ -15,7 +15,7 @@ namespace NzbDrone.Providers private static readonly Logger Logger = LogManager.GetLogger("Host.ServiceManager"); - + public virtual bool ServiceExist(string name) { @@ -32,7 +32,7 @@ namespace NzbDrone.Providers var installer = new ServiceProcessInstaller { - Account = ServiceAccount.NetworkService + Account = ServiceAccount.LocalSystem }; var serviceInstaller = new ServiceInstaller(); @@ -44,9 +44,9 @@ namespace NzbDrone.Providers serviceInstaller.Context = context; serviceInstaller.DisplayName = NzbDroneServiceName; serviceInstaller.ServiceName = NzbDroneServiceName; + serviceInstaller.Description = "NzbDrone Application Server"; serviceInstaller.StartType = ServiceStartMode.Automatic; - serviceInstaller.Parent = installer; serviceInstaller.Install(new ListDictionary()); @@ -63,5 +63,11 @@ namespace NzbDrone.Providers serviceInstaller.ServiceName = NzbDroneServiceName; serviceInstaller.Uninstall(null); } + + + public virtual void Run(ServiceBase service) + { + ServiceBase.Run(service); + } } } \ No newline at end of file diff --git a/NzbDrone/Router.cs b/NzbDrone/Router.cs index 7eba497b0..265ecce69 100644 --- a/NzbDrone/Router.cs +++ b/NzbDrone/Router.cs @@ -36,18 +36,9 @@ namespace NzbDrone { Logger.Info("Application mode: {0}", applicationMode); - _applicationServer.IsRunningAsService(); - - while (!Debugger.IsAttached) - { - Thread.Sleep(1000); - } - - - if (_enviromentProvider.IsRunningAsService) + if (!_enviromentProvider.IsUserInteractive) { - _applicationServer.StartService(); - + _serviceProvider.Run(_applicationServer); } else { @@ -74,7 +65,15 @@ namespace NzbDrone } case ApplicationMode.UninstallService: { - _serviceProvider.UnInstall(); + if (!_serviceProvider.ServiceExist(ServiceProvider.NzbDroneServiceName)) + { + _consoleProvider.PrintServiceDoestExist(); + } + else + { + _serviceProvider.UnInstall(); + } + break; } default: