Replaced ServiceInstall.bat/ServiceUninstall.bat with exe files that automatically elevate user permissions.

This commit is contained in:
kay.one 2012-01-16 23:12:22 -08:00
parent 4da2e1cb72
commit 850880de47
22 changed files with 537 additions and 26 deletions

View File

@ -1,4 +1,5 @@
using System.ServiceProcess; using System.IO;
using System.ServiceProcess;
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
@ -46,10 +47,10 @@ namespace NzbDrone.App.Test
[Test] [Test]
public void Route_should_call_install_service_when_application_mode_is_install() public void Route_should_call_install_service_when_application_mode_is_install()
{ {
WithStrictMocker(); var serviceProviderMock = Mocker.GetMock<ServiceProvider>(MockBehavior.Strict);
var serviceProviderMock = Mocker.GetMock<ServiceProvider>();
serviceProviderMock.Setup(c => c.Install(ServiceProvider.NZBDRONE_SERVICE_NAME)); serviceProviderMock.Setup(c => c.Install(ServiceProvider.NZBDRONE_SERVICE_NAME));
serviceProviderMock.Setup(c => c.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME)).Returns(false); serviceProviderMock.Setup(c => c.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME)).Returns(false);
serviceProviderMock.Setup(c => c.Start(ServiceProvider.NZBDRONE_SERVICE_NAME));
Mocker.GetMock<EnviromentProvider>().SetupGet(c => c.IsUserInteractive).Returns(true); Mocker.GetMock<EnviromentProvider>().SetupGet(c => c.IsUserInteractive).Returns(true);
Mocker.Resolve<Router>().Route(ApplicationMode.InstallService); Mocker.Resolve<Router>().Route(ApplicationMode.InstallService);
@ -61,7 +62,6 @@ namespace NzbDrone.App.Test
[Test] [Test]
public void Route_should_call_uninstall_service_when_application_mode_is_uninstall() public void Route_should_call_uninstall_service_when_application_mode_is_uninstall()
{ {
WithStrictMocker();
var serviceProviderMock = Mocker.GetMock<ServiceProvider>(); var serviceProviderMock = Mocker.GetMock<ServiceProvider>();
serviceProviderMock.Setup(c => c.UnInstall(ServiceProvider.NZBDRONE_SERVICE_NAME)); serviceProviderMock.Setup(c => c.UnInstall(ServiceProvider.NZBDRONE_SERVICE_NAME));
Mocker.GetMock<EnviromentProvider>().SetupGet(c => c.IsUserInteractive).Returns(true); Mocker.GetMock<EnviromentProvider>().SetupGet(c => c.IsUserInteractive).Returns(true);
@ -75,7 +75,6 @@ namespace NzbDrone.App.Test
[Test] [Test]
public void Route_should_call_console_service_when_application_mode_is_console() public void Route_should_call_console_service_when_application_mode_is_console()
{ {
WithStrictMocker();
var consoleProvider = Mocker.GetMock<ConsoleProvider>(); var consoleProvider = Mocker.GetMock<ConsoleProvider>();
var appServerProvider = Mocker.GetMock<ApplicationServer>(); var appServerProvider = Mocker.GetMock<ApplicationServer>();
consoleProvider.Setup(c => c.WaitForClose()); consoleProvider.Setup(c => c.WaitForClose());
@ -94,7 +93,6 @@ namespace NzbDrone.App.Test
[TestCase(ApplicationMode.Help)] [TestCase(ApplicationMode.Help)]
public void Route_should_call_service_start_when_run_in_service_more(ApplicationMode applicationMode) public void Route_should_call_service_start_when_run_in_service_more(ApplicationMode applicationMode)
{ {
WithStrictMocker();
var envMock = Mocker.GetMock<EnviromentProvider>(); var envMock = Mocker.GetMock<EnviromentProvider>();
var serviceProvider = Mocker.GetMock<ServiceProvider>(); var serviceProvider = Mocker.GetMock<ServiceProvider>();
@ -111,7 +109,6 @@ namespace NzbDrone.App.Test
[Test] [Test]
public void show_error_on_install_if_service_already_exist() public void show_error_on_install_if_service_already_exist()
{ {
WithStrictMocker();
var consoleMock = Mocker.GetMock<ConsoleProvider>(); var consoleMock = Mocker.GetMock<ConsoleProvider>();
var serviceMock = Mocker.GetMock<ServiceProvider>(); var serviceMock = Mocker.GetMock<ServiceProvider>();
Mocker.GetMock<EnviromentProvider>().SetupGet(c => c.IsUserInteractive).Returns(true); Mocker.GetMock<EnviromentProvider>().SetupGet(c => c.IsUserInteractive).Returns(true);
@ -127,7 +124,6 @@ namespace NzbDrone.App.Test
[Test] [Test]
public void show_error_on_uninstall_if_service_doesnt_exist() public void show_error_on_uninstall_if_service_doesnt_exist()
{ {
WithStrictMocker();
var consoleMock = Mocker.GetMock<ConsoleProvider>(); var consoleMock = Mocker.GetMock<ConsoleProvider>();
var serviceMock = Mocker.GetMock<ServiceProvider>(); var serviceMock = Mocker.GetMock<ServiceProvider>();
Mocker.GetMock<EnviromentProvider>().SetupGet(c => c.IsUserInteractive).Returns(true); Mocker.GetMock<EnviromentProvider>().SetupGet(c => c.IsUserInteractive).Returns(true);
@ -139,5 +135,30 @@ namespace NzbDrone.App.Test
Mocker.VerifyAllMocks(); Mocker.VerifyAllMocks();
} }
[Test]
public void should_delete_service_bat_files_if_they_exist()
{
WithTempAsAppPath();
var bat1 = @"c:\nzbdrone\ServiceInstall.bat";
var bat2 = @"c:\nzbdrone\ServiceUninstall.bat";
var bat3 = @"c:\nzbdrone\Someother.bat";
var file1 = @"c:\nzbdrone\ServiceInstall.exe";
var file2 = @"c:\nzbdrone\ServiceInstall.dat";
var files = new string[] {bat1, bat2, bat3, file1, file2};
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetFiles(VirtualPath, SearchOption.TopDirectoryOnly)).Returns(files);
Mocker.Resolve<Router>().Route(ApplicationMode.Console);
Mocker.GetMock<DiskProvider>().Verify(c=>c.DeleteFile(bat1));
Mocker.GetMock<DiskProvider>().Verify(c=>c.DeleteFile(bat2));
Mocker.GetMock<DiskProvider>().Verify(c=>c.DeleteFile(bat3),Times.Never());
Mocker.GetMock<DiskProvider>().Verify(c=>c.DeleteFile(file1),Times.Never());
Mocker.GetMock<DiskProvider>().Verify(c=>c.DeleteFile(file2),Times.Never());
}
} }
} }

View File

@ -63,6 +63,8 @@ namespace NzbDrone.Common.Test
serviceProvider.ServiceExist(TEMP_SERVICE_NAME).Should().BeTrue(); serviceProvider.ServiceExist(TEMP_SERVICE_NAME).Should().BeTrue();
serviceProvider.UnInstall(TEMP_SERVICE_NAME); serviceProvider.UnInstall(TEMP_SERVICE_NAME);
serviceProvider.ServiceExist(TEMP_SERVICE_NAME).Should().BeFalse(); serviceProvider.ServiceExist(TEMP_SERVICE_NAME).Should().BeFalse();
ExceptionVerification.ExpectedWarns(1);
} }
[Test] [Test]

View File

@ -65,6 +65,9 @@ namespace NzbDrone.Common
public virtual void UnInstall(string serviceName) public virtual void UnInstall(string serviceName)
{ {
Logger.Info("Uninstalling {0} service", serviceName); Logger.Info("Uninstalling {0} service", serviceName);
Stop(serviceName);
var serviceInstaller = new ServiceInstaller(); var serviceInstaller = new ServiceInstaller();
var context = new InstallContext("service_uninstall.log", null); var context = new InstallContext("service_uninstall.log", null);

View File

@ -14,11 +14,11 @@ namespace NzbDrone.Web.Models
public int Port { get; set; } public int Port { get; set; }
[DisplayName("Launch Browser")] [DisplayName("Launch Browser")]
[Description("Start default webrowser when NzbDrone starts?")] [Description("Start web browser when NzbDrone starts?")]
public bool LaunchBrowser { get; set; } public bool LaunchBrowser { get; set; }
[DisplayName("Authentication")] [DisplayName("Authentication")]
[Description("Secure the webserver with Authentication?")] [Description("Secure the server with authentication?")]
public AuthenticationType AuthenticationType { get; set; } public AuthenticationType AuthenticationType { get; set; }
public SelectList AuthTypeSelectList { get; set; } public SelectList AuthTypeSelectList { get; set; }

View File

@ -29,6 +29,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test.Common", "Test.Common"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Web.UI.Automation", "NzbDrone.Web.UI.Test\NzbDrone.Web.UI.Automation.csproj", "{3CCD64E1-84DA-4853-B7EF-98B02FD4E39E}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Web.UI.Automation", "NzbDrone.Web.UI.Test\NzbDrone.Web.UI.Automation.csproj", "{3CCD64E1-84DA-4853-B7EF-98B02FD4E39E}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ServiceHelpers", "ServiceHelpers", "{F9E67978-5CD6-4A5F-827B-4249711C0B02}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceInstall", "ServiceHelpers\ServiceInstall\ServiceInstall.csproj", "{6BCE712F-846D-4846-9D1B-A66B858DA755}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceUninstall", "ServiceHelpers\ServiceUninstall\ServiceUninstall.csproj", "{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -191,6 +197,30 @@ Global
{3CCD64E1-84DA-4853-B7EF-98B02FD4E39E}.Release|Mixed Platforms.Build.0 = Release|Any CPU {3CCD64E1-84DA-4853-B7EF-98B02FD4E39E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{3CCD64E1-84DA-4853-B7EF-98B02FD4E39E}.Release|x64.ActiveCfg = Release|Any CPU {3CCD64E1-84DA-4853-B7EF-98B02FD4E39E}.Release|x64.ActiveCfg = Release|Any CPU
{3CCD64E1-84DA-4853-B7EF-98B02FD4E39E}.Release|x86.ActiveCfg = Release|Any CPU {3CCD64E1-84DA-4853-B7EF-98B02FD4E39E}.Release|x86.ActiveCfg = Release|Any CPU
{6BCE712F-846D-4846-9D1B-A66B858DA755}.Debug|Any CPU.ActiveCfg = Debug|x86
{6BCE712F-846D-4846-9D1B-A66B858DA755}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{6BCE712F-846D-4846-9D1B-A66B858DA755}.Debug|Mixed Platforms.Build.0 = Debug|x86
{6BCE712F-846D-4846-9D1B-A66B858DA755}.Debug|x64.ActiveCfg = Debug|x86
{6BCE712F-846D-4846-9D1B-A66B858DA755}.Debug|x86.ActiveCfg = Debug|x86
{6BCE712F-846D-4846-9D1B-A66B858DA755}.Debug|x86.Build.0 = Debug|x86
{6BCE712F-846D-4846-9D1B-A66B858DA755}.Release|Any CPU.ActiveCfg = Release|x86
{6BCE712F-846D-4846-9D1B-A66B858DA755}.Release|Mixed Platforms.ActiveCfg = Release|x86
{6BCE712F-846D-4846-9D1B-A66B858DA755}.Release|Mixed Platforms.Build.0 = Release|x86
{6BCE712F-846D-4846-9D1B-A66B858DA755}.Release|x64.ActiveCfg = Release|x86
{6BCE712F-846D-4846-9D1B-A66B858DA755}.Release|x86.ActiveCfg = Release|x86
{6BCE712F-846D-4846-9D1B-A66B858DA755}.Release|x86.Build.0 = Release|x86
{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}.Debug|Any CPU.ActiveCfg = Debug|x86
{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}.Debug|Mixed Platforms.Build.0 = Debug|x86
{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}.Debug|x64.ActiveCfg = Debug|x86
{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}.Debug|x86.ActiveCfg = Debug|x86
{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}.Debug|x86.Build.0 = Debug|x86
{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}.Release|Any CPU.ActiveCfg = Release|x86
{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}.Release|Mixed Platforms.ActiveCfg = Release|x86
{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}.Release|Mixed Platforms.Build.0 = Release|x86
{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}.Release|x64.ActiveCfg = Release|x86
{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}.Release|x86.ActiveCfg = Release|x86
{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}.Release|x86.Build.0 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -204,6 +234,8 @@ Global
{3CCD64E1-84DA-4853-B7EF-98B02FD4E39E} = {57A04B72-8088-4F75-A582-1158CF8291F7} {3CCD64E1-84DA-4853-B7EF-98B02FD4E39E} = {57A04B72-8088-4F75-A582-1158CF8291F7}
{CADDFCE0-7509-4430-8364-2074E1EEFCA2} = {47697CDB-27B6-4B05-B4F8-0CBE6F6EDF97} {CADDFCE0-7509-4430-8364-2074E1EEFCA2} = {47697CDB-27B6-4B05-B4F8-0CBE6F6EDF97}
{FAFB5948-A222-4CF6-AD14-026BE7564802} = {47697CDB-27B6-4B05-B4F8-0CBE6F6EDF97} {FAFB5948-A222-4CF6-AD14-026BE7564802} = {47697CDB-27B6-4B05-B4F8-0CBE6F6EDF97}
{6BCE712F-846D-4846-9D1B-A66B858DA755} = {F9E67978-5CD6-4A5F-827B-4249711C0B02}
{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4} = {F9E67978-5CD6-4A5F-827B-4249711C0B02}
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

@ -56,6 +56,9 @@
<PropertyGroup> <PropertyGroup>
<StartupObject>NzbDrone.AppMain</StartupObject> <StartupObject>NzbDrone.AppMain</StartupObject>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <Reference Include="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<EmbedInteropTypes>True</EmbedInteropTypes> <EmbedInteropTypes>True</EmbedInteropTypes>
@ -94,13 +97,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="app.config" /> <None Include="app.config" />
<None Include="ServiceInstall.bat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="ServiceUninstall.bat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="NzbDrone.ico" /> <Content Include="NzbDrone.ico" />
@ -138,6 +135,10 @@
<PreBuildEvent> <PreBuildEvent>
</PreBuildEvent> </PreBuildEvent>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- 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. Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild"> <Target Name="BeforeBuild">

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Common; using NzbDrone.Common;
@ -15,17 +16,20 @@ namespace NzbDrone
private readonly ServiceProvider _serviceProvider; private readonly ServiceProvider _serviceProvider;
private readonly ConsoleProvider _consoleProvider; private readonly ConsoleProvider _consoleProvider;
private readonly EnviromentProvider _enviromentProvider; private readonly EnviromentProvider _enviromentProvider;
private readonly DiskProvider _diskProvider;
public Router(ApplicationServer applicationServer, ServiceProvider serviceProvider, ConsoleProvider consoleProvider, EnviromentProvider enviromentProvider) public Router(ApplicationServer applicationServer, ServiceProvider serviceProvider, ConsoleProvider consoleProvider, EnviromentProvider enviromentProvider, DiskProvider diskProvider)
{ {
_applicationServer = applicationServer; _applicationServer = applicationServer;
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_consoleProvider = consoleProvider; _consoleProvider = consoleProvider;
_enviromentProvider = enviromentProvider; _enviromentProvider = enviromentProvider;
_diskProvider = diskProvider;
} }
public void Route(IEnumerable<string> args) public void Route(IEnumerable<string> args)
{ {
Route(GetApplicationMode(args)); Route(GetApplicationMode(args));
} }
@ -33,6 +37,15 @@ namespace NzbDrone
{ {
Logger.Info("Application mode: {0}", applicationMode); Logger.Info("Application mode: {0}", applicationMode);
var batFiles = _diskProvider.GetFiles(_enviromentProvider.ApplicationPath, SearchOption.TopDirectoryOnly)
.Where(c => c.EndsWith(".bat", StringComparison.InvariantCultureIgnoreCase)).ToList();
foreach (var batFile in batFiles)
{
if (new FileInfo(batFile).Name.StartsWith("service", StringComparison.InvariantCultureIgnoreCase))
_diskProvider.DeleteFile(batFile);
}
//TODO:move this outside, it should be one of application modes (ApplicationMode.Service?) //TODO:move this outside, it should be one of application modes (ApplicationMode.Service?)
if (!_enviromentProvider.IsUserInteractive) if (!_enviromentProvider.IsUserInteractive)
{ {
@ -58,6 +71,7 @@ namespace NzbDrone
else else
{ {
_serviceProvider.Install(ServiceProvider.NZBDRONE_SERVICE_NAME); _serviceProvider.Install(ServiceProvider.NZBDRONE_SERVICE_NAME);
_serviceProvider.Start(ServiceProvider.NZBDRONE_SERVICE_NAME);
} }
break; break;
} }
@ -71,7 +85,7 @@ namespace NzbDrone
{ {
_serviceProvider.UnInstall(ServiceProvider.NZBDRONE_SERVICE_NAME); _serviceProvider.UnInstall(ServiceProvider.NZBDRONE_SERVICE_NAME);
} }
break; break;
} }
default: default:

View File

@ -1,4 +0,0 @@
@ECHO OFF
nzbdrone.exe /i
net start nzbdrone
pause

View File

@ -1,4 +0,0 @@
@ECHO OFF
net stop nzbdrone
nzbdrone.exe /u
pause

View File

@ -0,0 +1,16 @@
using System.Linq;
using System;
using InstallService;
namespace ServiceInstall
{
public static class Program
{
static void Main()
{
ServiceHelper.Run(@"/i");
Console.WriteLine("Press any key to continue");
Console.ReadLine();
}
}
}

View File

@ -0,0 +1,11 @@
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("InstallService")]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("13976baa-e5ba-42b2-8ad7-8d568b68a53b")]
[assembly: AssemblyVersion("0.0.0.*")]
[assembly: AssemblyFileVersion("0.0.0.*")]

View File

@ -0,0 +1,68 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Security.Principal;
namespace InstallService
{
internal static class ServiceHelper
{
private static string NzbDroneExe
{
get
{
return Path.Combine(new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName, "nzbdrone.exe");
}
}
private static bool IsAnAdministrator()
{
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
internal static void Run(string arg)
{
if (!File.Exists(NzbDroneExe))
{
Console.WriteLine("Unable to find NzbDrone.exe in the current directory.");
return;
}
if (!IsAnAdministrator())
{
Console.WriteLine("Access denied. Please run as administrator.");
return;
}
var startInfo = new ProcessStartInfo
{
FileName = NzbDroneExe,
Arguments = arg,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
var process = new Process { StartInfo = startInfo };
process.OutputDataReceived += (OnDataReceived);
process.ErrorDataReceived += (OnDataReceived);
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.WaitForExit();
}
private static void OnDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(e.Data);
}
}
}

View File

@ -0,0 +1,79 @@
<?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>{6BCE712F-846D-4846-9D1B-A66B858DA755}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ServiceInstall</RootNamespace>
<AssemblyName>ServiceInstall</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
</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>
</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>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup>
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<StartupObject>ServiceInstall.Program</StartupObject>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>green_puzzle.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\NzbDrone.Common\Properties\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ServiceHelper.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.manifest">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="green_puzzle.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\mt.exe" -manifest "$(ProjectDir)app.manifest" outputresource:"$(TargetDir)$(TargetFileName)";#1</PostBuildEvent>
</PropertyGroup>
<!-- 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,48 @@
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Specifying requestedExecutionLevel node will disable file and registry virtualization.
If you want to utilize File and Registry Virtualization for backward
compatibility then delete the requestedExecutionLevel node.
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of all Windows versions that this application is designed to work with. Windows will automatically select the most compatible environment.-->
<!-- If your application is designed to work with Windows 7, uncomment the following supportedOS node-->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
</application>
</compatibility>
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<!-- <dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>-->
</asmv1:assembly>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,16 @@
using System.Linq;
using System;
using UninstallService;
namespace ServiceUninstall
{
public static class Program
{
static void Main()
{
ServiceHelper.Run(@"/u");
Console.WriteLine("Press any key to continue");
Console.ReadLine();
}
}
}

View File

@ -0,0 +1,8 @@
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("UninstallService")]
[assembly: Guid("0a964b21-9de9-40b3-9378-0474fd5f21a8")]
[assembly: AssemblyVersion("0.0.0.*")]
[assembly: AssemblyFileVersion("0.0.0.*")]

View File

@ -0,0 +1,69 @@
using System.Linq;
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Security.Principal;
namespace UninstallService
{
internal static class ServiceHelper
{
private static string NzbDroneExe
{
get
{
return Path.Combine(new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName, "nzbdrone.exe");
}
}
private static bool IsAnAdministrator()
{
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
internal static void Run(string arg)
{
if (!File.Exists(NzbDroneExe))
{
Console.WriteLine("Unable to find NzbDrone.exe in the current directory.");
return;
}
if (!IsAnAdministrator())
{
Console.WriteLine("Access denied. Please run as administrator.");
return;
}
var startInfo = new ProcessStartInfo
{
FileName = NzbDroneExe,
Arguments = arg,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
var process = new Process { StartInfo = startInfo };
process.OutputDataReceived += (OnDataReceived);
process.ErrorDataReceived += (OnDataReceived);
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.WaitForExit();
}
private static void OnDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(e.Data);
}
}
}

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)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{700D0B95-95CD-43F3-B6C9-FAA0FC1358D4}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ServiceUninstall</RootNamespace>
<AssemblyName>ServiceUninstall</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
</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>
</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>
</PropertyGroup>
<PropertyGroup>
<StartupObject>ServiceUninstall.Program</StartupObject>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>red_puzzle.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\NzbDrone.Common\Properties\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ServiceHelper.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.manifest">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="red_puzzle.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PostBuildEvent>"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\mt.exe" -manifest "$(ProjectDir)app.manifest" outputresource:"$(TargetDir)$(TargetFileName)";#1</PostBuildEvent>
</PropertyGroup>
<!-- 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,48 @@
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Specifying requestedExecutionLevel node will disable file and registry virtualization.
If you want to utilize File and Registry Virtualization for backward
compatibility then delete the requestedExecutionLevel node.
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of all Windows versions that this application is designed to work with. Windows will automatically select the most compatible environment.-->
<!-- If your application is designed to work with Windows 7, uncomment the following supportedOS node-->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
</application>
</compatibility>
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<!-- <dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>-->
</asmv1:assembly>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -9,6 +9,9 @@ del nzbdrone*.zip /Q /F
xcopy IISExpress %TARGET%\IISExpress /E /V /I /Y xcopy IISExpress %TARGET%\IISExpress /E /V /I /Y
xcopy ServiceHelpers\ServiceInstall\bin\Release\*.exe %TARGET%\ /E /V /I /Y
xcopy ServiceHelpers\ServiceUninstall\bin\Release\*.exe %TARGET%\ /E /V /I /Y
xcopy NzbDrone\bin\Debug\*.* %TARGET%\ /E /V /I /Y xcopy NzbDrone\bin\Debug\*.* %TARGET%\ /E /V /I /Y
xcopy NzbDrone\bin\Release\*.* %TARGET%\ /E /V /I /Y xcopy NzbDrone\bin\Release\*.* %TARGET%\ /E /V /I /Y