Starting to add windows service support, making nzbdrone.exe unit testable.

This commit is contained in:
Keivan Beigi 2011-10-06 18:30:44 -07:00
parent 430fb9aead
commit f3ca3e97f9
36 changed files with 14144 additions and 65 deletions

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Providers;
namespace NzbDrone.App.Test
{
[TestFixture]
public class EnviromentControllerTest
{
[Test]
public void Is_user_interactive_should_be_false()
{
var enviromentController = new EnviromentProvider();
//Act
enviromentController.IsUserInteractive.Should().BeTrue();
}
[Test]
public void Log_path_should_not_be_empty()
{
var enviromentController = new EnviromentProvider();
//Act
enviromentController.LogPath.Should().NotBeBlank();
}
}
}

View File

@ -0,0 +1,80 @@
<?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)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NzbDrone.App.Test</RootNamespace>
<AssemblyName>NzbDrone.App.Test</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="FluentAssertions">
<HintPath>..\packages\FluentAssertions.1.5.0.0\Lib\.NetFramework 4.0\FluentAssertions.dll</HintPath>
</Reference>
<Reference Include="Moq">
<HintPath>..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.2.5.10.11092\lib\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="nunit.mocks">
<HintPath>..\packages\NUnit.2.5.10.11092\lib\nunit.mocks.dll</HintPath>
</Reference>
<Reference Include="pnunit.framework">
<HintPath>..\packages\NUnit.2.5.10.11092\lib\pnunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="EnviromentControllerTest.cs" />
<Compile Include="ServiceControllerTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone\NzbDrone.csproj">
<Project>{D12F7F2F-8A3C-415F-88FA-6DD061A84869}</Project>
<Name>NzbDrone</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.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

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("NzbDrone.App.Test")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("NzbDrone.App.Test")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b47d34ef-05e8-4826-8a57-9dd05106c964")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Providers;
namespace NzbDrone.App.Test
{
[TestFixture]
public class ServiceControllerTests
{
[Test]
public void Exists_should_find_spooler_service()
{
var serviceController = new ServiceProvider();
//Act
var exists = serviceController.ServiceExist("spooler");
exists.Should().BeTrue();
}
[Test]
public void Exists_should_not_find_random_service()
{
var serviceController = new ServiceProvider();
//Act
var exists = serviceController.ServiceExist("random_service_name");
exists.Should().BeFalse();
}
[Test]
public void Service_should_be_installed_and_then_uninstalled()
{
var serviceController = new ServiceProvider();
//Act
serviceController.ServiceExist(ServiceProvider.NzbDroneServiceName).Should().BeFalse();
serviceController.Install();
serviceController.ServiceExist(ServiceProvider.NzbDroneServiceName).Should().BeTrue();
serviceController.UnInstall();
serviceController.ServiceExist(ServiceProvider.NzbDroneServiceName).Should().BeFalse();
}
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentAssertions" version="1.5.0.0" />
<package id="Moq" version="4.0.10827" />
<package id="NUnit" version="2.5.10.11092" />
</packages>

View File

@ -21,7 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>

View File

@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Core.Test", "NzbDr
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{57A04B72-8088-4F75-A582-1158CF8291F7}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{57A04B72-8088-4F75-A582-1158CF8291F7}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.App.Test", "NzbDrone.App.Test\NzbDrone.App.Test.csproj", "{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -77,12 +79,25 @@ Global
{193ADD3B-792B-4173-8E4C-5A3F8F0237F0}.Release|Mixed Platforms.Build.0 = Release|Any CPU {193ADD3B-792B-4173-8E4C-5A3F8F0237F0}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{193ADD3B-792B-4173-8E4C-5A3F8F0237F0}.Release|x64.ActiveCfg = Release|Any CPU {193ADD3B-792B-4173-8E4C-5A3F8F0237F0}.Release|x64.ActiveCfg = Release|Any CPU
{193ADD3B-792B-4173-8E4C-5A3F8F0237F0}.Release|x86.ActiveCfg = Release|Any CPU {193ADD3B-792B-4173-8E4C-5A3F8F0237F0}.Release|x86.ActiveCfg = Release|Any CPU
{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}.Debug|x64.ActiveCfg = Debug|Any CPU
{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}.Debug|x86.ActiveCfg = Debug|Any CPU
{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}.Release|Any CPU.Build.0 = Release|Any CPU
{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}.Release|x64.ActiveCfg = Release|Any CPU
{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{193ADD3B-792B-4173-8E4C-5A3F8F0237F0} = {57A04B72-8088-4F75-A582-1158CF8291F7} {193ADD3B-792B-4173-8E4C-5A3F8F0237F0} = {57A04B72-8088-4F75-A582-1158CF8291F7}
{C0EA1A40-91AD-4EEB-BD16-2DDDEBD20AE5} = {57A04B72-8088-4F75-A582-1158CF8291F7}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
EnterpriseLibraryConfigurationToolBinariesPath = packages\Unity.2.1.505.0\lib\NET35 EnterpriseLibraryConfigurationToolBinariesPath = packages\Unity.2.1.505.0\lib\NET35

View File

@ -30,7 +30,7 @@
<BootstrapperEnabled>true</BootstrapperEnabled> <BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
@ -73,18 +73,25 @@
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
<Reference Include="System.Configuration.Install" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Providers\EnviromentProvider.cs" />
<Compile Include="NzbDroneService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ProcessAttacher.cs" /> <Compile Include="ProcessAttacher.cs" />
<Compile Include="Config.cs" /> <Compile Include="Providers\ConfigProvider.cs" />
<Compile Include="IISController.cs" /> <Compile Include="Providers\IISControllerProvider.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Providers\ServiceProvider.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="app.config" /> <None Include="app.config" />

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
namespace NzbDrone
{
class NzbDroneService : ServiceBase
{
protected override void OnStart(string[] args)
{
base.OnStart(args);
}
protected override void OnStop()
{
base.OnStop();
}
}
}

View File

@ -5,19 +5,26 @@ using System.Threading;
using System.Timers; using System.Timers;
using Exceptioneer.WindowsFormsClient; using Exceptioneer.WindowsFormsClient;
using NLog; using NLog;
using NzbDrone.Providers;
namespace NzbDrone namespace NzbDrone
{ {
internal static class Program internal static class Program
{ {
private static readonly Logger Logger = LogManager.GetLogger("Application"); private static readonly Logger Logger = LogManager.GetLogger("Application");
static readonly ConfigProvider ConfigProvider = new ConfigProvider();
static readonly IISControllerProvider IISController = new IISControllerProvider(ConfigProvider);
private static void Main() private static void Main()
{ {
try try
{ {
Config.ConfigureNlog();
Config.CreateDefaultConfigFile();
Logger.Info("Starting NZBDrone. Start-up Path:'{0}'", Config.ProjectRoot); ConfigProvider.ConfigureNlog();
ConfigProvider.CreateDefaultConfigFile();
Logger.Info("Starting NZBDrone. Start-up Path:'{0}'", ConfigProvider.ApplicationRoot);
Thread.CurrentThread.Name = "Host"; Thread.CurrentThread.Name = "Host";
Process currentProcess = Process.GetCurrentProcess(); Process currentProcess = Process.GetCurrentProcess();
@ -40,7 +47,7 @@ namespace NzbDrone
Attach(); Attach();
#endif #endif
if (!Environment.UserInteractive || !Config.LaunchBrowser) if (!Environment.UserInteractive || !ConfigProvider.LaunchBrowser)
{ {
try try
{ {
@ -86,13 +93,13 @@ namespace NzbDrone
} }
if (IISController.IISProcess != null) if (IISControllerProvider.IISProcess != null)
{ {
IISController.IISProcess.Refresh(); IISControllerProvider.IISProcess.Refresh();
if (IISController.IISProcess.PriorityClass != ProcessPriorityClass.Normal && IISController.IISProcess.PriorityClass != ProcessPriorityClass.AboveNormal) if (IISControllerProvider.IISProcess.PriorityClass != ProcessPriorityClass.Normal && IISControllerProvider.IISProcess.PriorityClass != ProcessPriorityClass.AboveNormal)
{ {
SetPriority(IISController.IISProcess); SetPriority(IISControllerProvider.IISProcess);
} }
} }
} }
@ -101,7 +108,7 @@ namespace NzbDrone
{ {
Logger.Info("Updating [{0}] process priority from {1} to {2}", Logger.Info("Updating [{0}] process priority from {1} to {2}",
process.ProcessName, process.ProcessName,
IISController.IISProcess.PriorityClass, IISControllerProvider.IISProcess.PriorityClass,
ProcessPriorityClass.Normal); ProcessPriorityClass.Normal);
process.PriorityClass = ProcessPriorityClass.Normal; process.PriorityClass = ProcessPriorityClass.Normal;
} }

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Configuration;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -7,17 +6,14 @@ using System.Xml.Linq;
using NLog; using NLog;
using NLog.Config; using NLog.Config;
namespace NzbDrone namespace NzbDrone.Providers
{ {
internal class Config internal class ConfigProvider
{ {
private static string _projectRoot = string.Empty;
internal static string ProjectRoot internal virtual string ApplicationRoot
{ {
get get
{
if (string.IsNullOrEmpty(_projectRoot))
{ {
var appDir = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory; var appDir = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory;
@ -27,40 +23,42 @@ namespace NzbDrone
appDir = appDir.Parent; appDir = appDir.Parent;
} }
_projectRoot = appDir.FullName; return appDir.FullName;
}
return _projectRoot;
} }
} }
internal static int Port internal virtual int Port
{ {
get { return GetValueInt("Port"); } get { return GetValueInt("Port"); }
} }
internal static bool LaunchBrowser internal virtual bool LaunchBrowser
{ {
get { return GetValueBoolean("LaunchBrowser"); } get { return GetValueBoolean("LaunchBrowser"); }
} }
internal static string AppDataDirectory internal virtual string AppDataDirectory
{ {
get { return Path.Combine(ProjectRoot, "NzbDrone.Web", "App_Data"); } get { return Path.Combine(ApplicationRoot, "NzbDrone.Web", "App_Data"); }
} }
internal static string ConfigFile internal virtual string ConfigFile
{ {
get { return Path.Combine(AppDataDirectory, "Config.xml"); } get { return Path.Combine(AppDataDirectory, "Config.xml"); }
} }
internal static void ConfigureNlog() internal virtual string IISFolder
{ {
LogManager.Configuration = new XmlLoggingConfiguration( get { return Path.Combine(ApplicationRoot, @"IISExpress\"); }
Path.Combine(ProjectRoot, "NzbDrone.Web\\log.config"), false);
} }
internal static void CreateDefaultConfigFile() internal virtual void ConfigureNlog()
{
LogManager.Configuration = new XmlLoggingConfiguration(
Path.Combine(ApplicationRoot, "NzbDrone.Web\\log.config"), false);
}
internal virtual void CreateDefaultConfigFile()
{ {
//Create the config file here //Create the config file here
Directory.CreateDirectory(AppDataDirectory); Directory.CreateDirectory(AppDataDirectory);
@ -71,7 +69,7 @@ namespace NzbDrone
} }
} }
internal static void WriteDefaultConfig() internal virtual void WriteDefaultConfig()
{ {
var xDoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes")); var xDoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
@ -84,7 +82,7 @@ namespace NzbDrone
xDoc.Save(ConfigFile); xDoc.Save(ConfigFile);
} }
private static string GetValue(string key, string parent = null) private string GetValue(string key, string parent = null)
{ {
var xDoc = XDocument.Load(ConfigFile); var xDoc = XDocument.Load(ConfigFile);
var config = xDoc.Descendants("Config").Single(); var config = xDoc.Descendants("Config").Single();
@ -99,12 +97,12 @@ namespace NzbDrone
return value; return value;
} }
private static int GetValueInt(string key, string parent = null) private int GetValueInt(string key, string parent = null)
{ {
return Convert.ToInt32(GetValue(key, parent)); return Convert.ToInt32(GetValue(key, parent));
} }
private static bool GetValueBoolean(string key, string parent = null) private bool GetValueBoolean(string key, string parent = null)
{ {
return Convert.ToBoolean(GetValue(key, parent)); return Convert.ToBoolean(GetValue(key, parent));
} }

View File

@ -0,0 +1,17 @@
using System;
namespace NzbDrone.Providers
{
public class EnviromentProvider
{
public virtual String LogPath
{
get { return Environment.CurrentDirectory; }
}
public virtual bool IsUserInteractive
{
get { return Environment.UserInteractive; }
}
}
}

View File

@ -9,15 +9,16 @@ using System.Xml.Linq;
using System.Xml.XPath; using System.Xml.XPath;
using NLog; using NLog;
namespace NzbDrone namespace NzbDrone.Providers
{ {
internal class IISController internal class IISControllerProvider
{ {
private readonly ConfigProvider _configProvider;
private static readonly Logger IISLogger = LogManager.GetLogger("IISExpress"); private static readonly Logger IISLogger = LogManager.GetLogger("IISExpress");
private static readonly Logger Logger = LogManager.GetLogger("IISController"); private static readonly Logger Logger = LogManager.GetLogger("IISControllerProvider");
private static readonly string IISFolder = Path.Combine(Config.ProjectRoot, @"IISExpress\");
private static readonly string IISExe = Path.Combine(IISFolder, @"iisexpress.exe"); private readonly string IISExe;
private static readonly string IISConfigPath = Path.Combine(IISFolder, "AppServer", "applicationhost.config"); private readonly string IISConfigPath;
private static Timer _pingTimer; private static Timer _pingTimer;
private static int _pingFailCounter; private static int _pingFailCounter;
@ -25,19 +26,26 @@ namespace NzbDrone
public static Process IISProcess { get; private set; } public static Process IISProcess { get; private set; }
internal static string AppUrl public IISControllerProvider(ConfigProvider configProvider)
{ {
get { return string.Format("http://localhost:{0}/", Config.Port); } _configProvider = configProvider;
IISExe = Path.Combine(_configProvider.IISFolder, @"iisexpress.exe");
IISConfigPath = Path.Combine(_configProvider.IISFolder, "AppServer", "applicationhost.config");
} }
internal static Process StartServer() internal string AppUrl
{
get { return string.Format("http://localhost:{0}/", _configProvider.Port); }
}
internal Process StartServer()
{ {
Logger.Info("Preparing IISExpress Server..."); Logger.Info("Preparing IISExpress Server...");
IISProcess = new Process(); IISProcess = new Process();
IISProcess.StartInfo.FileName = IISExe; IISProcess.StartInfo.FileName = IISExe;
IISProcess.StartInfo.Arguments = String.Format("/config:\"{0}\" /trace:i", IISConfigPath);//"/config:"""" /trace:i"; IISProcess.StartInfo.Arguments = String.Format("/config:\"{0}\" /trace:i", IISConfigPath);//"/config:"""" /trace:i";
IISProcess.StartInfo.WorkingDirectory = Config.ProjectRoot; IISProcess.StartInfo.WorkingDirectory = _configProvider.ApplicationRoot;
IISProcess.StartInfo.UseShellExecute = false; IISProcess.StartInfo.UseShellExecute = false;
IISProcess.StartInfo.RedirectStandardOutput = true; IISProcess.StartInfo.RedirectStandardOutput = true;
@ -49,7 +57,7 @@ namespace NzbDrone
IISProcess.ErrorDataReceived += (OnErrorDataReceived); IISProcess.ErrorDataReceived += (OnErrorDataReceived);
//Set Variables for the config file. //Set Variables for the config file.
IISProcess.StartInfo.EnvironmentVariables.Add("NZBDRONE_PATH", Config.ProjectRoot); IISProcess.StartInfo.EnvironmentVariables.Add("NZBDRONE_PATH", _configProvider.ApplicationRoot);
IISProcess.StartInfo.EnvironmentVariables.Add("NZBDRONE_PID", Process.GetCurrentProcess().Id.ToString()); IISProcess.StartInfo.EnvironmentVariables.Add("NZBDRONE_PID", Process.GetCurrentProcess().Id.ToString());
try try
@ -88,7 +96,7 @@ namespace NzbDrone
IISLogger.Error(e.Data); IISLogger.Error(e.Data);
} }
internal static void StopServer() internal void StopServer()
{ {
KillProcess(IISProcess); KillProcess(IISProcess);
@ -109,7 +117,7 @@ namespace NzbDrone
} }
} }
private static void RestartServer() private void RestartServer()
{ {
_pingTimer.Stop(); _pingTimer.Stop();
Logger.Warn("Attempting to restart server."); Logger.Warn("Attempting to restart server.");
@ -117,7 +125,7 @@ namespace NzbDrone
StartServer(); StartServer();
} }
private static void PingServer(object sender, ElapsedEventArgs e) private void PingServer(object sender, ElapsedEventArgs e)
{ {
try try
{ {
@ -144,7 +152,7 @@ namespace NzbDrone
} }
} }
private static void OnOutputDataReceived(object s, DataReceivedEventArgs e) private void OnOutputDataReceived(object s, DataReceivedEventArgs e)
{ {
if (e == null || String.IsNullOrWhiteSpace(e.Data) || e.Data.StartsWith("Request started:") || if (e == null || String.IsNullOrWhiteSpace(e.Data) || e.Data.StartsWith("Request started:") ||
e.Data.StartsWith("Request ended:") || e.Data == ("IncrementMessages called")) e.Data.StartsWith("Request ended:") || e.Data == ("IncrementMessages called"))
@ -159,12 +167,12 @@ namespace NzbDrone
IISLogger.Trace(e.Data); IISLogger.Trace(e.Data);
} }
private static void UpdateIISConfig() private void UpdateIISConfig()
{ {
string configPath = Path.Combine(IISFolder, @"AppServer\applicationhost.config"); string configPath = Path.Combine(_configProvider.IISFolder, @"AppServer\applicationhost.config");
Logger.Info(@"Server configuration file: {0}", configPath); Logger.Info(@"Server configuration file: {0}", configPath);
Logger.Info(@"Configuring server to: [http://localhost:{0}]", Config.Port); Logger.Info(@"Configuring server to: [http://localhost:{0}]", _configProvider.Port);
var configXml = XDocument.Load(configPath); var configXml = XDocument.Load(configPath);
@ -175,19 +183,19 @@ namespace NzbDrone
bindings.Add( bindings.Add(
new XElement("binding", new XElement("binding",
new XAttribute("protocol", "http"), new XAttribute("protocol", "http"),
new XAttribute("bindingInformation", String.Format("*:{0}:localhost", Config.Port)) new XAttribute("bindingInformation", String.Format("*:{0}:localhost", _configProvider.Port))
)); ));
bindings.Add( bindings.Add(
new XElement("binding", new XElement("binding",
new XAttribute("protocol", "http"), new XAttribute("protocol", "http"),
new XAttribute("bindingInformation", String.Format("*:{0}:", Config.Port)) new XAttribute("bindingInformation", String.Format("*:{0}:", _configProvider.Port))
)); ));
configXml.Save(configPath); configXml.Save(configPath);
} }
private static void KillProcess(Process process) private void KillProcess(Process process)
{ {
if (process != null && !process.HasExited) if (process != null && !process.HasExited)
{ {
@ -199,7 +207,7 @@ namespace NzbDrone
} }
} }
public static string NormalizePath(string path) public string NormalizePath(string path)
{ {
if (String.IsNullOrWhiteSpace(path)) if (String.IsNullOrWhiteSpace(path))
throw new ArgumentException("Path can not be null or empty"); throw new ArgumentException("Path can not be null or empty");

View File

@ -0,0 +1,63 @@
using System;
using System.Collections.Specialized;
using System.Configuration.Install;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
using NLog;
namespace NzbDrone.Providers
{
public class ServiceProvider
{
public const string NzbDroneServiceName = "NzbDrone";
private static readonly Logger Logger = LogManager.GetLogger("ServiceManager");
public bool ServiceExist(string name)
{
return
System.ServiceProcess.ServiceController.GetServices().Any(
s => String.Equals(s.ServiceName, name, StringComparison.InvariantCultureIgnoreCase));
}
public virtual void Install()
{
Logger.Info("Installing service '{0}'", NzbDroneServiceName);
var installer = new ServiceProcessInstaller
{
Account = ServiceAccount.NetworkService
};
var serviceInstaller = new ServiceInstaller();
String[] cmdline = { @"/assemblypath=" + Assembly.GetExecutingAssembly().Location };
var context = new InstallContext("service_install.log", cmdline);
serviceInstaller.Context = context;
serviceInstaller.DisplayName = NzbDroneServiceName;
serviceInstaller.ServiceName = NzbDroneServiceName;
serviceInstaller.StartType = ServiceStartMode.Automatic;
serviceInstaller.Parent = installer;
serviceInstaller.Install(new ListDictionary());
Logger.Info("Service Has installed successfully.");
}
public virtual void UnInstall()
{
var serviceInstaller = new ServiceInstaller();
var context = new InstallContext("install.log", null);
serviceInstaller.Context = context;
serviceInstaller.ServiceName = NzbDroneServiceName;
serviceInstaller.Uninstall(null);
}
}
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,4 +3,5 @@
<repository path="..\NzbDrone.Web\packages.config" /> <repository path="..\NzbDrone.Web\packages.config" />
<repository path="..\NzbDrone.Core.Test\packages.config" /> <repository path="..\NzbDrone.Core.Test\packages.config" />
<repository path="..\NzbDrone.Core\packages.config" /> <repository path="..\NzbDrone.Core\packages.config" />
<repository path="..\NzbDrone.App.Test\packages.config" />
</repositories> </repositories>