Hidden startup, shutodwn and restart

New: Run without console window by default
New: Added NzbDrone.Console to run with console window
New: Shutdown from UI
New: Restart from UI
This commit is contained in:
Mark McDowall 2013-01-06 00:11:14 -08:00
parent 17d9d0cc4f
commit 125703a2fa
29 changed files with 504 additions and 98 deletions

View File

@ -31,6 +31,12 @@ namespace NzbDrone.App.Test
[TestCase("/u", ApplicationMode.UninstallService)] [TestCase("/u", ApplicationMode.UninstallService)]
[TestCase("-U", ApplicationMode.UninstallService)] [TestCase("-U", ApplicationMode.UninstallService)]
[TestCase("-u", ApplicationMode.UninstallService)] [TestCase("-u", ApplicationMode.UninstallService)]
[TestCase("s", ApplicationMode.Silent)]
[TestCase("S", ApplicationMode.Silent)]
[TestCase("/S", ApplicationMode.Silent)]
[TestCase("/s", ApplicationMode.Silent)]
[TestCase("-S", ApplicationMode.Silent)]
[TestCase("-s", ApplicationMode.Silent)]
public void GetApplicationMode_single_arg(string arg, ApplicationMode mode) public void GetApplicationMode_single_arg(string arg, ApplicationMode mode)
{ {
Router.GetApplicationMode(new[] { arg }).Should().Be(mode); Router.GetApplicationMode(new[] { arg }).Should().Be(mode);

View File

@ -20,6 +20,7 @@ namespace NzbDrone.Common
Console.WriteLine(" Commands:"); Console.WriteLine(" Commands:");
Console.WriteLine(" /i Install the application as a Windows Service ({0}).", ServiceProvider.NZBDRONE_SERVICE_NAME); Console.WriteLine(" /i Install the application as a Windows Service ({0}).", ServiceProvider.NZBDRONE_SERVICE_NAME);
Console.WriteLine(" /u Uninstall already installed Windows Service ({0}).", ServiceProvider.NZBDRONE_SERVICE_NAME); Console.WriteLine(" /u Uninstall already installed Windows Service ({0}).", ServiceProvider.NZBDRONE_SERVICE_NAME);
Console.WriteLine(" /s Run NzbDrone without a Console Window.");
Console.WriteLine(" <No Arguments> Run application in console mode."); Console.WriteLine(" <No Arguments> Run application in console mode.");
} }

View File

@ -74,7 +74,7 @@ namespace NzbDrone.Common
if (!string.IsNullOrWhiteSpace(applicationPath)) if (!string.IsNullOrWhiteSpace(applicationPath))
return applicationPath; return applicationPath;
applicationPath = CrawlToRoot(NzbDronePathFromEnviroment); applicationPath = CrawlToRoot(NzbDronePathFromEnvironment);
if (!string.IsNullOrWhiteSpace(applicationPath)) if (!string.IsNullOrWhiteSpace(applicationPath))
return applicationPath; return applicationPath;
@ -146,7 +146,7 @@ namespace NzbDrone.Common
} }
} }
public virtual string NzbDronePathFromEnviroment public virtual string NzbDronePathFromEnvironment
{ {
get get
{ {

View File

@ -51,7 +51,6 @@ namespace NzbDrone.Common
startInfo.RedirectStandardError = true; startInfo.RedirectStandardError = true;
startInfo.CreateNoWindow = true; startInfo.CreateNoWindow = true;
startInfo.EnvironmentVariables[EnvironmentProvider.NZBDRONE_PATH] = _environmentProvider.ApplicationPath; startInfo.EnvironmentVariables[EnvironmentProvider.NZBDRONE_PATH] = _environmentProvider.ApplicationPath;
startInfo.EnvironmentVariables[EnvironmentProvider.NZBDRONE_PID] = Process.GetCurrentProcess().Id.ToString(); startInfo.EnvironmentVariables[EnvironmentProvider.NZBDRONE_PID] = Process.GetCurrentProcess().Id.ToString();
@ -74,6 +73,9 @@ namespace NzbDrone.Common
iisProcess.BeginOutputReadLine(); iisProcess.BeginOutputReadLine();
ServerStarted = true; ServerStarted = true;
iisProcess.EnableRaisingEvents = true;
iisProcess.Exited += IIS_EXITED;
} }
private static void OnErrorDataReceived(object sender, DataReceivedEventArgs e) private static void OnErrorDataReceived(object sender, DataReceivedEventArgs e)
@ -84,7 +86,6 @@ namespace NzbDrone.Common
IISLogger.Error(e.Data); IISLogger.Error(e.Data);
} }
public void RestartServer() public void RestartServer()
{ {
ServerStarted = false; ServerStarted = false;
@ -93,7 +94,6 @@ namespace NzbDrone.Common
StartServer(); StartServer();
} }
public virtual void StopServer() public virtual void StopServer()
{ {
_processProvider.Kill(IISProcessId); _processProvider.Kill(IISProcessId);
@ -114,6 +114,10 @@ namespace NzbDrone.Common
} }
} }
public void IIS_EXITED(object obj, EventArgs args)
{
RestartServer();
}
private void OnOutputDataReceived(object s, DataReceivedEventArgs e) private void OnOutputDataReceived(object s, DataReceivedEventArgs e)
{ {
@ -123,6 +127,5 @@ namespace NzbDrone.Common
Console.WriteLine(e.Data); Console.WriteLine(e.Data);
} }
} }
} }

View File

@ -9,11 +9,11 @@ namespace NzbDrone.Common
private const string APP_DATA = "App_Data\\"; private const string APP_DATA = "App_Data\\";
public const string IIS_FOLDER = "IISExpress"; public const string IIS_FOLDER = "IISExpress";
public const string IIS_EXE = "iisexpress.exe"; public const string IIS_EXE = "iisexpress.exe";
private const string LOG_CONFIG_FILE = "log.config"; private const string LOG_CONFIG_FILE = "log.config";
private const string APP_CONFIG_FILE = "config.xml"; private const string APP_CONFIG_FILE = "config.xml";
public const string NZBDRONE_EXE = "NzbDrone.exe";
public const string NZBDRONE_DB_FILE = "nzbdrone.sdf"; public const string NZBDRONE_DB_FILE = "nzbdrone.sdf";
public const string LOG_DB_FILE = "log.sdf"; public const string LOG_DB_FILE = "log.sdf";
@ -156,5 +156,10 @@ namespace NzbDrone.Common
{ {
return Path.Combine(environmentProvider.GetAppDataPath(), BACKUP_ZIP_FILE); return Path.Combine(environmentProvider.GetAppDataPath(), BACKUP_ZIP_FILE);
} }
public static string GetNzbDroneExe(this EnvironmentProvider environmentProvider)
{
return Path.Combine(environmentProvider.ApplicationPath, NZBDRONE_EXE);
}
} }
} }

View File

@ -11,6 +11,7 @@ namespace NzbDrone.Common
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public static readonly string NzbDroneProccessName = "NzbDrone"; public static readonly string NzbDroneProccessName = "NzbDrone";
public static readonly string NzbDroneConsoleProccessName = "NzbDrone.Console";
public virtual ProcessInfo GetCurrentProcess() public virtual ProcessInfo GetCurrentProcess()
{ {
@ -107,6 +108,5 @@ namespace NzbDrone.Common
Name = process.ProcessName Name = process.ProcessName
}; };
} }
} }
} }

View File

@ -136,6 +136,8 @@ namespace NzbDrone.Core
Kernel.Bind<IJob>().To<CleanupRecycleBinJob>().InSingletonScope(); Kernel.Bind<IJob>().To<CleanupRecycleBinJob>().InSingletonScope();
Kernel.Bind<IJob>().To<EmptyRecycleBinJob>().InSingletonScope(); Kernel.Bind<IJob>().To<EmptyRecycleBinJob>().InSingletonScope();
Kernel.Bind<IJob>().To<XemUpdateJob>().InSingletonScope(); Kernel.Bind<IJob>().To<XemUpdateJob>().InSingletonScope();
Kernel.Bind<IJob>().To<AppShutdownJob>().InSingletonScope();
Kernel.Bind<IJob>().To<AppRestartJob>().InSingletonScope();
Kernel.Get<JobProvider>().Initialize(); Kernel.Get<JobProvider>().Initialize();
Kernel.Get<WebTimer>().StartTimer(30); Kernel.Get<WebTimer>().StartTimer(30);

View File

@ -0,0 +1,51 @@
using System;
using System.Linq;
using System.Diagnostics;
using System.IO;
using NLog;
using Ninject;
using NzbDrone.Common;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
namespace NzbDrone.Core.Jobs
{
public class AppRestartJob : IJob
{
private readonly EnvironmentProvider _environmentProvider;
private readonly ProcessProvider _processProvider;
private readonly ServiceProvider _serviceProvider;
private readonly IISProvider _iisProvider;
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
[Inject]
public AppRestartJob(EnvironmentProvider environmentProvider, ProcessProvider processProvider,
ServiceProvider serviceProvider, IISProvider iisProvider)
{
_environmentProvider = environmentProvider;
_processProvider = processProvider;
_serviceProvider = serviceProvider;
_iisProvider = iisProvider;
}
public string Name
{
get { return "Restart NzbDrone"; }
}
public TimeSpan DefaultInterval
{
get { return TimeSpan.FromTicks(0); }
}
public virtual void Start(ProgressNotification notification, dynamic options)
{
notification.CurrentMessage = "Restarting NzbDrone";
logger.Info("Restarting NzbDrone");
_iisProvider.StopServer();
}
}
}

View File

@ -0,0 +1,61 @@
using System;
using System.Linq;
using System.Diagnostics;
using System.IO;
using NLog;
using Ninject;
using NzbDrone.Common;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
namespace NzbDrone.Core.Jobs
{
public class AppShutdownJob : IJob
{
private readonly EnvironmentProvider _environmentProvider;
private readonly ProcessProvider _processProvider;
private readonly ServiceProvider _serviceProvider;
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
[Inject]
public AppShutdownJob(EnvironmentProvider environmentProvider, ProcessProvider processProvider, ServiceProvider serviceProvider)
{
_environmentProvider = environmentProvider;
_processProvider = processProvider;
_serviceProvider = serviceProvider;
}
public string Name
{
get { return "Shutdown NzbDrone"; }
}
public TimeSpan DefaultInterval
{
get { return TimeSpan.FromTicks(0); }
}
public virtual void Start(ProgressNotification notification, dynamic options)
{
notification.CurrentMessage = "Shutting down NzbDrone";
logger.Info("Shutting down NzbDrone");
if (_serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME)
&& _serviceProvider.IsServiceRunning(ServiceProvider.NZBDRONE_SERVICE_NAME))
{
logger.Debug("Stopping NzbDrone Service");
_serviceProvider.Stop(ServiceProvider.NZBDRONE_SERVICE_NAME);
}
else
{
logger.Debug("Stopping NzbDrone console");
var pid = _environmentProvider.NzbDroneProcessIdFromEnviroment;
_processProvider.Kill(pid);
}
}
}
}

View File

@ -268,6 +268,8 @@
<Compile Include="Helpers\SabnzbdPriorityTypeConverter.cs" /> <Compile Include="Helpers\SabnzbdPriorityTypeConverter.cs" />
<Compile Include="Helpers\XElementHelper.cs" /> <Compile Include="Helpers\XElementHelper.cs" />
<Compile Include="Jobs\CleanupRecycleBinJob.cs" /> <Compile Include="Jobs\CleanupRecycleBinJob.cs" />
<Compile Include="Jobs\AppShutdownJob.cs" />
<Compile Include="Jobs\AppRestartJob.cs" />
<Compile Include="Jobs\XemUpdateJob.cs" /> <Compile Include="Jobs\XemUpdateJob.cs" />
<Compile Include="Jobs\EmptyRecycleBinJob.cs" /> <Compile Include="Jobs\EmptyRecycleBinJob.cs" />
<Compile Include="Jobs\RefreshEpsiodeMetadata.cs" /> <Compile Include="Jobs\RefreshEpsiodeMetadata.cs" />

View File

@ -242,7 +242,7 @@ namespace NzbDrone.Update.Test
.Verify(c => c.Start(It.IsAny<string>()), Times.Never()); .Verify(c => c.Start(It.IsAny<string>()), Times.Never());
Mocker.GetMock<ProcessProvider>() Mocker.GetMock<ProcessProvider>()
.Verify(c => c.Start(TARGET_FOLDER + "nzbdrone.exe"), Times.Once()); .Verify(c => c.Start(TARGET_FOLDER + "NzbDrone.exe"), Times.Once());
} }

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NzbDrone.Update
{
public enum AppType
{
Normal,
Console,
Service
}
}

View File

@ -51,6 +51,7 @@
<Compile Include="..\NzbDrone.Common\Properties\SharedAssemblyInfo.cs"> <Compile Include="..\NzbDrone.Common\Properties\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link> <Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile> </Compile>
<Compile Include="AppType.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Providers\UpdateProvider.cs" /> <Compile Include="Providers\UpdateProvider.cs" />

View File

@ -45,20 +45,19 @@ namespace NzbDrone.Update.Providers
logger.Info("Verifying Update Folder"); logger.Info("Verifying Update Folder");
if (!_diskProvider.FolderExists(_environmentProvider.GetUpdatePackageFolder())) if (!_diskProvider.FolderExists(_environmentProvider.GetUpdatePackageFolder()))
throw new DirectoryNotFoundException("Update folder doesn't exist " + _environmentProvider.GetUpdatePackageFolder()); throw new DirectoryNotFoundException("Update folder doesn't exist " + _environmentProvider.GetUpdatePackageFolder());
} }
public virtual void Start(string targetFolder) public virtual void Start(string targetFolder)
{ {
Verify(targetFolder); Verify(targetFolder);
bool isService = false; AppType appType = AppType.Normal;
logger.Info("Stopping all running services"); logger.Info("Stopping all running services");
if (_serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME) if (_serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME)
&& _serviceProvider.IsServiceRunning(ServiceProvider.NZBDRONE_SERVICE_NAME)) && _serviceProvider.IsServiceRunning(ServiceProvider.NZBDRONE_SERVICE_NAME))
{ {
isService = true; appType = AppType.Service;
_serviceProvider.Stop(ServiceProvider.NZBDRONE_SERVICE_NAME); _serviceProvider.Stop(ServiceProvider.NZBDRONE_SERVICE_NAME);
} }
@ -68,6 +67,14 @@ namespace NzbDrone.Update.Providers
var processes = _processProvider.GetProcessByName(ProcessProvider.NzbDroneProccessName); var processes = _processProvider.GetProcessByName(ProcessProvider.NzbDroneProccessName);
foreach (var processInfo in processes) foreach (var processInfo in processes)
{ {
appType = AppType.Normal;
_processProvider.Kill(processInfo.Id);
}
var consoleProcesses = _processProvider.GetProcessByName(ProcessProvider.NzbDroneConsoleProccessName);
foreach (var processInfo in consoleProcesses)
{
appType = AppType.Console;
_processProvider.Kill(processInfo.Id); _processProvider.Kill(processInfo.Id);
} }
@ -77,7 +84,6 @@ namespace NzbDrone.Update.Providers
logger.Info("Creating backup of existing installation"); logger.Info("Creating backup of existing installation");
_diskProvider.CopyDirectory(targetFolder, _environmentProvider.GetUpdateBackUpFolder()); _diskProvider.CopyDirectory(targetFolder, _environmentProvider.GetUpdateBackUpFolder());
logger.Info("Moving update package to target"); logger.Info("Moving update package to target");
try try
@ -100,7 +106,7 @@ namespace NzbDrone.Update.Providers
} }
finally finally
{ {
StartNzbDrone(isService, targetFolder); StartNzbDrone(appType, targetFolder);
} }
} }
@ -112,15 +118,19 @@ namespace NzbDrone.Update.Providers
} }
private void StartNzbDrone(bool isService, string targetFolder) private void StartNzbDrone(AppType appType, string targetFolder)
{ {
if (isService) if (appType == AppType.Service)
{ {
_serviceProvider.Start(ServiceProvider.NZBDRONE_SERVICE_NAME); _serviceProvider.Start(ServiceProvider.NZBDRONE_SERVICE_NAME);
} }
else if(appType == AppType.Console)
{
_processProvider.Start(Path.Combine(targetFolder, "NzbDrone.Console.exe"));
}
else else
{ {
_processProvider.Start(Path.Combine(targetFolder, "nzbdrone.exe")); _processProvider.Start(Path.Combine(targetFolder, "NzbDrone.exe"));
} }
} }
} }

View File

@ -26,11 +26,6 @@ namespace NzbDrone.Web.Controllers
_diskProvider = diskProvider; _diskProvider = diskProvider;
} }
public ActionResult Index()
{
return View();
}
public FileContentResult File() public FileContentResult File()
{ {
string log = string.Empty; string log = string.Empty;

View File

@ -36,6 +36,16 @@ namespace NzbDrone.Web.Controllers
_statsProvider = statsProvider; _statsProvider = statsProvider;
} }
public ActionResult Index()
{
return View();
}
public ActionResult Logs()
{
return View();
}
public ActionResult Jobs() public ActionResult Jobs()
{ {
var queue = _jobProvider.Queue.Select(c => new JobQueueItemModel var queue = _jobProvider.Queue.Select(c => new JobQueueItemModel
@ -80,32 +90,6 @@ namespace NzbDrone.Web.Controllers
return View((object)serialized); return View((object)serialized);
} }
public JsonResult SelectConfigAjax()
{
var config = _configProvider.All();
return Json(new
{
iTotalRecords = config.Count(),
iTotalDisplayRecords = config.Count(),
aaData = config
}, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public string SaveConfigAjax(string id, string value)
{
_configProvider.SetValue(id, value);
return value;
}
[HttpPost]
public string InsertConfigAjax(string key, string value)
{
_configProvider.SetValue(key, value);
return key;
}
//PostDownloadView //PostDownloadView
public ActionResult PendingProcessing() public ActionResult PendingProcessing()
{ {
@ -184,5 +168,43 @@ namespace NzbDrone.Web.Controllers
return View(model); return View(model);
} }
public JsonResult Restart()
{
_jobProvider.QueueJob(typeof(AppRestartJob));
return JsonNotificationResult.Info("NzbDrone will restart shortly");
}
public JsonResult Shutdown()
{
_jobProvider.QueueJob(typeof(AppShutdownJob));
return JsonNotificationResult.Info("NzbDrone will shutdown shortly");
}
public JsonResult SelectConfigAjax()
{
var config = _configProvider.All();
return Json(new
{
iTotalRecords = config.Count(),
iTotalDisplayRecords = config.Count(),
aaData = config
}, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public string SaveConfigAjax(string id, string value)
{
_configProvider.SetValue(id, value);
return value;
}
[HttpPost]
public string InsertConfigAjax(string key, string value)
{
_configProvider.SetValue(key, value);
return key;
}
} }
} }

View File

@ -312,6 +312,8 @@
<Compile Include="Models\UpcomingEpisodeModel.cs" /> <Compile Include="Models\UpcomingEpisodeModel.cs" />
<Compile Include="Models\UpdateModel.cs" /> <Compile Include="Models\UpdateModel.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Content Include="Views\System\Index.cshtml" />
<Content Include="Views\System\Logs.cshtml" />
<None Include="_bin_deployableAssemblies\x86\sqlcese40.dll" /> <None Include="_bin_deployableAssemblies\x86\sqlcese40.dll" />
<None Include="_bin_deployableAssemblies\x86\sqlceqp40.dll" /> <None Include="_bin_deployableAssemblies\x86\sqlceqp40.dll" />
<None Include="_bin_deployableAssemblies\x86\sqlceme40.dll" /> <None Include="_bin_deployableAssemblies\x86\sqlceme40.dll" />
@ -528,7 +530,6 @@
<Content Include="Views\Shared\Footer.cshtml" /> <Content Include="Views\Shared\Footer.cshtml" />
<Content Include="Views\_ViewStart.cshtml" /> <Content Include="Views\_ViewStart.cshtml" />
<Content Include="Views\History\Index.cshtml" /> <Content Include="Views\History\Index.cshtml" />
<Content Include="Views\Log\Index.cshtml" />
<Content Include="Views\Upcoming\Index.cshtml" /> <Content Include="Views\Upcoming\Index.cshtml" />
<Content Include="Views\Series\Index.cshtml" /> <Content Include="Views\Series\Index.cshtml" />
<Content Include="Views\Shared\Error.cshtml" /> <Content Include="Views\Shared\Error.cshtml" />

View File

@ -29,7 +29,7 @@
@MvcHtmlString.Create(Html.CurrentControllerLink("History", "Index", "History")) @MvcHtmlString.Create(Html.CurrentControllerLink("History", "Index", "History"))
@MvcHtmlString.Create(Html.CurrentControllerLink("Missing", "Index", "Missing")) @MvcHtmlString.Create(Html.CurrentControllerLink("Missing", "Index", "Missing"))
@MvcHtmlString.Create(Html.CurrentControllerLink("Settings", "Index", "Settings")) @MvcHtmlString.Create(Html.CurrentControllerLink("Settings", "Index", "Settings"))
@MvcHtmlString.Create(Html.CurrentControllerLink("Logs", "Index", "Log")) @MvcHtmlString.Create(Html.CurrentControllerLink("System", "Index", "System"))
<li id="donate" title="Donate to support the development of NzbDrone"><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=KRTE52U3XJDSQ" target="_blank">Donate</a></li> <li id="donate" title="Donate to support the development of NzbDrone"><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=KRTE52U3XJDSQ" target="_blank">Donate</a></li>
</ul> </ul>
</div> </div>

View File

@ -0,0 +1,32 @@
@using NzbDrone.Web.Helpers
@{
ViewBag.Title = "System";
}
@section HeaderContent
{
@Html.IncludeCss("Settings.css")
<style>
.controls {
width: 620px;
padding: 14px;
}
</style>
}
@section ActionMenu{
<ul class="sub-menu">
<li>@Ajax.ActionLink("Restart", "Restart", "System", null, null, new { Title = "Restart NzbDrone" })</li>
<li>@Ajax.ActionLink("Shutdown", "Shutdown", "System", null, null, new { Title = "Shutdown NzbDrone" })</li>
<li>@Html.ActionLink("Logs", "Logs", "System")</li>
</ul>
}
<div id="stylized">
<div class="controls">
<label class="labelClass"> Backup Configuration
<span class="small">Backup your Configuration file and Database</span>
</label>
<input type="button" value="Backup" onclick="window.location='../System/Backup'; return false;" class="inputClass" />
</div>
</div>

View File

@ -51,6 +51,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{1E6B3C
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Api", "NzbDrone.Api\NzbDrone.Api.csproj", "{FD286DF8-2D3A-4394-8AD5-443FADE55FB2}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Api", "NzbDrone.Api\NzbDrone.Api.csproj", "{FD286DF8-2D3A-4394-8AD5-443FADE55FB2}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Console", "NzbDrone\NzbDrone.Console.csproj", "{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -494,6 +496,30 @@ Global
{FD286DF8-2D3A-4394-8AD5-443FADE55FB2}.Services|Mixed Platforms.Build.0 = Release|Any CPU {FD286DF8-2D3A-4394-8AD5-443FADE55FB2}.Services|Mixed Platforms.Build.0 = Release|Any CPU
{FD286DF8-2D3A-4394-8AD5-443FADE55FB2}.Services|x64.ActiveCfg = Release|Any CPU {FD286DF8-2D3A-4394-8AD5-443FADE55FB2}.Services|x64.ActiveCfg = Release|Any CPU
{FD286DF8-2D3A-4394-8AD5-443FADE55FB2}.Services|x86.ActiveCfg = Release|Any CPU {FD286DF8-2D3A-4394-8AD5-443FADE55FB2}.Services|x86.ActiveCfg = Release|Any CPU
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Debug|Any CPU.ActiveCfg = Debug|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Debug|Mixed Platforms.Build.0 = Debug|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Debug|x64.ActiveCfg = Debug|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Debug|x86.ActiveCfg = Debug|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Debug|x86.Build.0 = Debug|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Pilot|Any CPU.ActiveCfg = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Pilot|Mixed Platforms.ActiveCfg = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Pilot|Mixed Platforms.Build.0 = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Pilot|x64.ActiveCfg = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Pilot|x86.ActiveCfg = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Pilot|x86.Build.0 = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Release|Any CPU.ActiveCfg = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Release|Mixed Platforms.ActiveCfg = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Release|Mixed Platforms.Build.0 = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Release|x64.ActiveCfg = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Release|x86.ActiveCfg = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Release|x86.Build.0 = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Services|Any CPU.ActiveCfg = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Services|Mixed Platforms.ActiveCfg = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Services|Mixed Platforms.Build.0 = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Services|x64.ActiveCfg = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Services|x86.ActiveCfg = Release|x86
{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}.Services|x86.Build.0 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -45,7 +45,5 @@ namespace NzbDrone
MonitoringProvider.AppDomainException(e); MonitoringProvider.AppDomainException(e);
} }
} }
} }
} }

View File

@ -5,6 +5,7 @@
Console, Console,
Help, Help,
InstallService, InstallService,
UninstallService UninstallService,
Service
} }
} }

View File

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{3DCA7B58-B8B3-49AC-9D9E-56F4A0460976}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NzbDrone</RootNamespace>
<AssemblyName>NzbDrone.Console</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>true</UseVSHostingProcess>
<CodeAnalysisRuleSet>BasicCorrectnessRules.ruleset</CodeAnalysisRuleSet>
<IntermediateOutputPath>C:\Users\Mark\AppData\Local\Temp\vs32F1.tmp\x86\Debug\</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<IntermediateOutputPath>C:\Users\Mark\AppData\Local\Temp\vs32F1.tmp\x86\Release\</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>NzbDrone.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<StartupObject>NzbDrone.AppMain</StartupObject>
</PropertyGroup>
<PropertyGroup>
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
</PropertyGroup>
<ItemGroup>
<Reference Include="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="EnvDTE80, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="Ninject, Version=3.0.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Ninject.3.0.1.10\lib\net40\Ninject.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=2.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.2.0.0.2000\lib\net40\NLog.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.ServiceProcess" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\NzbDrone.Common\Properties\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="ApplicationServer.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="CentralDispatch.cs" />
<Compile Include="Model\ApplicationMode.cs" />
<Compile Include="Providers\DebuggerProvider.cs" />
<Compile Include="ProcessAttacher.cs" />
<Compile Include="AppMain.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Providers\MonitoringProvider.cs" />
<Compile Include="Router.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="NzbDrone.ico" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Common\NzbDrone.Common.csproj">
<Project>{F2BE0FDF-6E47-4827-A420-DD4EF82407F8}</Project>
<Name>NzbDrone.Common</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<!-- 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.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -6,7 +6,7 @@
<ProductVersion>8.0.30703</ProductVersion> <ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{D12F7F2F-8A3C-415F-88FA-6DD061A84869}</ProjectGuid> <ProjectGuid>{D12F7F2F-8A3C-415F-88FA-6DD061A84869}</ProjectGuid>
<OutputType>Exe</OutputType> <OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NzbDrone</RootNamespace> <RootNamespace>NzbDrone</RootNamespace>
<AssemblyName>NzbDrone</AssemblyName> <AssemblyName>NzbDrone</AssemblyName>

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Common; using NzbDrone.Common;
@ -15,73 +16,94 @@ namespace NzbDrone
private readonly ServiceProvider _serviceProvider; private readonly ServiceProvider _serviceProvider;
private readonly ConsoleProvider _consoleProvider; private readonly ConsoleProvider _consoleProvider;
private readonly EnvironmentProvider _environmentProvider; private readonly EnvironmentProvider _environmentProvider;
private readonly ProcessProvider _processProvider;
public Router(ApplicationServer applicationServer, ServiceProvider serviceProvider, ConsoleProvider consoleProvider, EnvironmentProvider environmentProvider) public Router(ApplicationServer applicationServer, ServiceProvider serviceProvider,
ConsoleProvider consoleProvider, EnvironmentProvider environmentProvider,
ProcessProvider processProvider)
{ {
_applicationServer = applicationServer; _applicationServer = applicationServer;
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_consoleProvider = consoleProvider; _consoleProvider = consoleProvider;
_environmentProvider = environmentProvider; _environmentProvider = environmentProvider;
_processProvider = processProvider;
} }
public void Route(IEnumerable<string> args) public void Route(IEnumerable<string> args)
{ {
Route(GetApplicationMode(args)); Route(GetApplicationMode(args));
} }
public void Route(ApplicationMode applicationMode) public void Route(ApplicationMode applicationMode)
{ {
logger.Info("Application mode: {0}", applicationMode); logger.Info("Application mode: {0}", applicationMode);
//TODO:move this outside, it should be one of application modes (ApplicationMode.Service?) if(!_environmentProvider.IsUserInteractive)
if (!_environmentProvider.IsUserInteractive)
{ {
_serviceProvider.Run(_applicationServer); applicationMode = ApplicationMode.Service;
} }
else
{
switch (applicationMode) switch (applicationMode)
{ {
case ApplicationMode.Service:
{
_serviceProvider.Run(_applicationServer);
break;
}
case ApplicationMode.Console: case ApplicationMode.Console:
{
_applicationServer.Start();
_consoleProvider.WaitForClose();
break;
}
case ApplicationMode.InstallService:
{
if (_serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME))
{ {
_applicationServer.Start(); _consoleProvider.PrintServiceAlreadyExist();
_consoleProvider.WaitForClose();
break;
} }
case ApplicationMode.InstallService: else
{ {
if (_serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME)) _serviceProvider.Install(ServiceProvider.NZBDRONE_SERVICE_NAME);
{ _serviceProvider.Start(ServiceProvider.NZBDRONE_SERVICE_NAME);
_consoleProvider.PrintServiceAlreadyExist();
}
else
{
_serviceProvider.Install(ServiceProvider.NZBDRONE_SERVICE_NAME);
_serviceProvider.Start(ServiceProvider.NZBDRONE_SERVICE_NAME);
}
break;
} }
case ApplicationMode.UninstallService: break;
}
case ApplicationMode.UninstallService:
{
if (!_serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME))
{ {
if (!_serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME)) _consoleProvider.PrintServiceDoestExist();
{ }
_consoleProvider.PrintServiceDoestExist(); else
} {
else _serviceProvider.UnInstall(ServiceProvider.NZBDRONE_SERVICE_NAME);
{ }
_serviceProvider.UnInstall(ServiceProvider.NZBDRONE_SERVICE_NAME);
}
break; break;
} }
default: case ApplicationMode.Silent:
{ {
_consoleProvider.PrintHelp(); var startInfo = new ProcessStartInfo();
break; startInfo.FileName = _environmentProvider.GetNzbDroneExe();
} startInfo.WorkingDirectory = _environmentProvider.ApplicationPath;
}
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.CreateNoWindow = true;
_processProvider.Start(startInfo);
Environment.Exit(0);
break;
}
default:
{
_consoleProvider.PrintHelp();
break;
}
} }
} }
@ -97,6 +119,7 @@ namespace NzbDrone
if (arg == "i") return ApplicationMode.InstallService; if (arg == "i") return ApplicationMode.InstallService;
if (arg == "u") return ApplicationMode.UninstallService; if (arg == "u") return ApplicationMode.UninstallService;
if (arg == "s") return ApplicationMode.Silent;
return ApplicationMode.Help; return ApplicationMode.Help;
} }

View File

@ -13,7 +13,7 @@ namespace ServiceInstall
{ {
get get
{ {
return Path.Combine(new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName, "nzbdrone.exe"); return Path.Combine(new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName, "NzbDrone.Console.exe");
} }
} }

View File

@ -13,7 +13,7 @@ namespace ServiceUninstall
{ {
get get
{ {
return Path.Combine(new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName, "nzbdrone.exe"); return Path.Combine(new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName, "NzbDrone.Console.exe");
} }
} }