mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
Add back Windows Service functionality
This commit is contained in:
@@ -6,6 +6,7 @@ using Jackett.Common.Models.Config;
|
|||||||
using Jackett.Common.Services;
|
using Jackett.Common.Services;
|
||||||
using Jackett.Common.Services.Interfaces;
|
using Jackett.Common.Services.Interfaces;
|
||||||
using Jackett.Common.Utils.Clients;
|
using Jackett.Common.Utils.Clients;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NLog.Config;
|
using NLog.Config;
|
||||||
using NLog.Targets;
|
using NLog.Targets;
|
||||||
@@ -19,8 +20,10 @@ namespace Jackett.Server
|
|||||||
public static class Helper
|
public static class Helper
|
||||||
{
|
{
|
||||||
public static IContainer ApplicationContainer { get; set; }
|
public static IContainer ApplicationContainer { get; set; }
|
||||||
|
public static IApplicationLifetime applicationLifetime;
|
||||||
private static bool _automapperInitialised = false;
|
private static bool _automapperInitialised = false;
|
||||||
|
public static ConsoleOptions ConsoleOptions { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
@@ -32,13 +35,13 @@ namespace Jackett.Server
|
|||||||
_automapperInitialised = true;
|
_automapperInitialised = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessRuntimeSettings();
|
ProcessSettings();
|
||||||
|
|
||||||
//Load the indexers
|
//Load the indexers
|
||||||
ServerService.Initalize();
|
ServerService.Initalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessRuntimeSettings()
|
private static void ProcessSettings()
|
||||||
{
|
{
|
||||||
RuntimeSettings runtimeSettings = ServerConfiguration.RuntimeSettings;
|
RuntimeSettings runtimeSettings = ServerConfiguration.RuntimeSettings;
|
||||||
|
|
||||||
@@ -74,11 +77,83 @@ namespace Jackett.Server
|
|||||||
Logger.Info("Jackett Data will be stored in: " + runtimeSettings.CustomDataFolder);
|
Logger.Info("Jackett Data will be stored in: " + runtimeSettings.CustomDataFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use Proxy
|
|
||||||
if (runtimeSettings.ProxyConnection != null)
|
if (runtimeSettings.ProxyConnection != null)
|
||||||
{
|
{
|
||||||
Logger.Info("Proxy enabled. " + runtimeSettings.ProxyConnection);
|
Logger.Info("Proxy enabled. " + runtimeSettings.ProxyConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ConsoleOptions.Install || ConsoleOptions.Uninstall || ConsoleOptions.StartService || ConsoleOptions.StopService || ConsoleOptions.ReserveUrls)
|
||||||
|
{
|
||||||
|
bool isWindows = Environment.OSVersion.Platform == PlatformID.Win32NT;
|
||||||
|
|
||||||
|
if (!isWindows)
|
||||||
|
{
|
||||||
|
Logger.Error($"ReserveUrls and service arguments only apply to Windows, please remove them from your start arguments");
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ====== Actions ===== */
|
||||||
|
|
||||||
|
// Install service
|
||||||
|
if (ConsoleOptions.Install)
|
||||||
|
{
|
||||||
|
Logger.Info("Initiating Jackett service install");
|
||||||
|
ServiceConfigService.Install();
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uninstall service
|
||||||
|
if (ConsoleOptions.Uninstall)
|
||||||
|
{
|
||||||
|
Logger.Info("Initiating Jackett service uninstall");
|
||||||
|
ServiceConfigService.Uninstall();
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start Service
|
||||||
|
if (ConsoleOptions.StartService)
|
||||||
|
{
|
||||||
|
if (!ServiceConfigService.ServiceRunning())
|
||||||
|
{
|
||||||
|
Logger.Info("Initiating Jackett service start");
|
||||||
|
ServiceConfigService.Start();
|
||||||
|
}
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop Service
|
||||||
|
if (ConsoleOptions.StopService)
|
||||||
|
{
|
||||||
|
if (ServiceConfigService.ServiceRunning())
|
||||||
|
{
|
||||||
|
Logger.Info("Initiating Jackett service stop");
|
||||||
|
ServiceConfigService.Stop();
|
||||||
|
}
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reserve urls
|
||||||
|
if (ConsoleOptions.ReserveUrls)
|
||||||
|
{
|
||||||
|
Logger.Info("Initiating ReserveUrls");
|
||||||
|
ServerService.ReserveUrls(doInstall: true);
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RestartWebHost()
|
||||||
|
{
|
||||||
|
Logger.Info("Restart of the web application host (not process) initiated");
|
||||||
|
Program.isWebHostRestart = true;
|
||||||
|
applicationLifetime.StopApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StopWebHost()
|
||||||
|
{
|
||||||
|
Logger.Info("Jackett is being stopped");
|
||||||
|
applicationLifetime.StopApplication();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IConfigurationService ConfigService
|
public static IConfigurationService ConfigService
|
||||||
@@ -97,6 +172,14 @@ namespace Jackett.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IServiceConfigService ServiceConfigService
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ApplicationContainer.Resolve<IServiceConfigService>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static ServerConfig ServerConfiguration
|
public static ServerConfig ServerConfiguration
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" />
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="2.1.0" />
|
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="2.1.0" />
|
||||||
|
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.5.0" />
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />
|
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@@ -21,15 +21,17 @@ namespace Jackett.Server
|
|||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
public static IConfiguration Configuration { get; set; }
|
public static IConfiguration Configuration { get; set; }
|
||||||
|
|
||||||
private static RuntimeSettings Settings { get; set; }
|
private static RuntimeSettings Settings { get; set; }
|
||||||
|
public static bool isWebHostRestart = false;
|
||||||
|
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
|
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
|
||||||
|
|
||||||
var parser = new Parser();
|
var commandLineParser = new Parser();
|
||||||
var optionsResult = parser.ParseArguments<ConsoleOptions>(args);
|
var optionsResult = commandLineParser.ParseArguments<ConsoleOptions>(args);
|
||||||
|
var runtimeDictionary = new Dictionary<string, string>();
|
||||||
|
ConsoleOptions consoleOptions = new ConsoleOptions();
|
||||||
|
|
||||||
optionsResult.WithNotParsed(errors =>
|
optionsResult.WithNotParsed(errors =>
|
||||||
{
|
{
|
||||||
@@ -41,8 +43,6 @@ namespace Jackett.Server
|
|||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
var runtimeDictionary = new Dictionary<string, string>();
|
|
||||||
ConsoleOptions consoleOptions = new ConsoleOptions();
|
|
||||||
optionsResult.WithParsed(options =>
|
optionsResult.WithParsed(options =>
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(options.Client))
|
if (string.IsNullOrEmpty(options.Client))
|
||||||
@@ -56,6 +56,8 @@ namespace Jackett.Server
|
|||||||
runtimeDictionary = GetValues(Settings);
|
runtimeDictionary = GetValues(Settings);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.ConsoleOptions = consoleOptions;
|
||||||
|
|
||||||
var builder = new ConfigurationBuilder();
|
var builder = new ConfigurationBuilder();
|
||||||
builder.AddInMemoryCollection(runtimeDictionary);
|
builder.AddInMemoryCollection(runtimeDictionary);
|
||||||
|
|
||||||
@@ -111,7 +113,12 @@ namespace Jackett.Server
|
|||||||
tempContainer.Dispose();
|
tempContainer.Dispose();
|
||||||
tempContainer = null;
|
tempContainer = null;
|
||||||
|
|
||||||
|
//TODO Handle scenario where user changes the port in the UI and we need to restart the WebHost with new port
|
||||||
|
do
|
||||||
|
{
|
||||||
|
isWebHostRestart = false;
|
||||||
CreateWebHostBuilder(args, url).Build().Run();
|
CreateWebHostBuilder(args, url).Build().Run();
|
||||||
|
} while (isWebHostRestart);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string, string> GetValues(object obj)
|
public static Dictionary<string, string> GetValues(object obj)
|
||||||
|
@@ -1,28 +1,27 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.Configuration.Install;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using Jackett.Common.Services.Interfaces;
|
using Jackett.Common.Services.Interfaces;
|
||||||
|
|
||||||
namespace Jackett.Services
|
namespace Jackett.Server.Services
|
||||||
{
|
{
|
||||||
|
|
||||||
public class ServiceConfigService : IServiceConfigService
|
public class ServiceConfigService : IServiceConfigService
|
||||||
{
|
{
|
||||||
private const string NAME = "Jackett";
|
private const string NAME = "Jackett";
|
||||||
private const string DESCRIPTION = "Additional indexers for Sonarr";
|
private const string DESCRIPTION = "API Support for your favorite torrent trackers";
|
||||||
private const string SERVICEEXE = "JackettService.exe";
|
private const string SERVICEEXE = "JackettService.exe";
|
||||||
|
|
||||||
private IConfigurationService configService;
|
private IConfigurationService configService;
|
||||||
|
private IProcessService processService;
|
||||||
private Logger logger;
|
private Logger logger;
|
||||||
|
|
||||||
public ServiceConfigService(IConfigurationService c, Logger l)
|
public ServiceConfigService(IConfigurationService c, IProcessService p, Logger l)
|
||||||
{
|
{
|
||||||
configService = c;
|
configService = c;
|
||||||
|
processService = p;
|
||||||
logger = l;
|
logger = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,30 +64,17 @@ namespace Jackett.Services
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var installer = new ServiceProcessInstaller
|
|
||||||
{
|
|
||||||
Account = ServiceAccount.LocalSystem
|
|
||||||
};
|
|
||||||
|
|
||||||
var serviceInstaller = new ServiceInstaller();
|
|
||||||
|
|
||||||
var exePath = Path.Combine(configService.ApplicationFolder(), SERVICEEXE);
|
var exePath = Path.Combine(configService.ApplicationFolder(), SERVICEEXE);
|
||||||
if (!File.Exists(exePath) && Debugger.IsAttached)
|
if (!File.Exists(exePath) && Debugger.IsAttached)
|
||||||
{
|
{
|
||||||
exePath = Path.Combine(configService.ApplicationFolder(), "..\\..\\..\\Jackett.Service\\bin\\Debug", SERVICEEXE);
|
exePath = Path.Combine(configService.ApplicationFolder(), "..\\..\\..\\Jackett.Service\\bin\\Debug", SERVICEEXE);
|
||||||
}
|
}
|
||||||
|
|
||||||
string[] cmdline = { @"/assemblypath=" + exePath};
|
string arg = $"create {NAME} start= auto binpath= \"{exePath}\" DisplayName= {NAME}";
|
||||||
|
|
||||||
var context = new InstallContext("jackettservice_install.log", cmdline);
|
processService.StartProcessAndLog("sc.exe", arg, true);
|
||||||
serviceInstaller.Context = context;
|
|
||||||
serviceInstaller.DisplayName = NAME;
|
|
||||||
serviceInstaller.ServiceName = NAME;
|
|
||||||
serviceInstaller.Description = DESCRIPTION;
|
|
||||||
serviceInstaller.StartType = ServiceStartMode.Automatic;
|
|
||||||
serviceInstaller.Parent = installer;
|
|
||||||
|
|
||||||
serviceInstaller.Install(new ListDictionary());
|
processService.StartProcessAndLog("sc.exe", $"description {NAME} \"{DESCRIPTION}\"", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,11 +82,7 @@ namespace Jackett.Services
|
|||||||
{
|
{
|
||||||
RemoveService();
|
RemoveService();
|
||||||
|
|
||||||
var serviceInstaller = new ServiceInstaller();
|
processService.StartProcessAndLog("sc.exe", $"delete {NAME}", true);
|
||||||
var context = new InstallContext("jackettservice_uninstall.log", null);
|
|
||||||
serviceInstaller.Context = context;
|
|
||||||
serviceInstaller.ServiceName = NAME;
|
|
||||||
serviceInstaller.Uninstall(null);
|
|
||||||
|
|
||||||
logger.Info("The service was uninstalled.");
|
logger.Info("The service was uninstalled.");
|
||||||
}
|
}
|
||||||
@@ -120,12 +102,18 @@ namespace Jackett.Services
|
|||||||
|
|
||||||
service.Refresh();
|
service.Refresh();
|
||||||
if (service.Status == ServiceControllerStatus.Stopped)
|
if (service.Status == ServiceControllerStatus.Stopped)
|
||||||
|
{
|
||||||
logger.Info("Service stopped.");
|
logger.Info("Service stopped.");
|
||||||
else
|
|
||||||
logger.Error("Failed to stop the service");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
logger.Error("Failed to stop the service");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
logger.Warn("The service was already stopped");
|
logger.Warn("The service was already stopped");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -81,6 +81,7 @@ namespace Jackett.Server
|
|||||||
builder.RegisterType<SecuityService>().As<ISecuityService>();
|
builder.RegisterType<SecuityService>().As<ISecuityService>();
|
||||||
builder.RegisterType<ServerService>().As<IServerService>();
|
builder.RegisterType<ServerService>().As<IServerService>();
|
||||||
builder.RegisterType<ProtectionService>().As<IProtectionService>();
|
builder.RegisterType<ProtectionService>().As<IProtectionService>();
|
||||||
|
builder.RegisterType<ServiceConfigService>().As<IServiceConfigService>();
|
||||||
|
|
||||||
IContainer container = builder.Build();
|
IContainer container = builder.Build();
|
||||||
Helper.ApplicationContainer = container;
|
Helper.ApplicationContainer = container;
|
||||||
@@ -94,7 +95,7 @@ namespace Jackett.Server
|
|||||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationLifetime)
|
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationLifetime)
|
||||||
{
|
{
|
||||||
applicationLifetime.ApplicationStopping.Register(OnShutdown);
|
applicationLifetime.ApplicationStopping.Register(OnShutdown);
|
||||||
|
Helper.applicationLifetime = applicationLifetime;
|
||||||
app.UseResponseCompression();
|
app.UseResponseCompression();
|
||||||
|
|
||||||
app.UseDeveloperExceptionPage();
|
app.UseDeveloperExceptionPage();
|
||||||
|
13
src/Jackett.Service.Windows/Jackett.Service.Windows.csproj
Normal file
13
src/Jackett.Service.Windows/Jackett.Service.Windows.csproj
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<AssemblyName>JackettService</AssemblyName>
|
||||||
|
<TargetFramework>net461</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Windows.Compatibility" Version="2.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Jackett.Server\Jackett.Server.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
17
src/Jackett.Service.Windows/Program.cs
Normal file
17
src/Jackett.Service.Windows/Program.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System.ServiceProcess;
|
||||||
|
|
||||||
|
namespace Jackett.Service.Windows
|
||||||
|
{
|
||||||
|
internal static class Program
|
||||||
|
{
|
||||||
|
private static void Main()
|
||||||
|
{
|
||||||
|
ServiceBase[] ServicesToRun;
|
||||||
|
ServicesToRun = new ServiceBase[]
|
||||||
|
{
|
||||||
|
new Service()
|
||||||
|
};
|
||||||
|
ServiceBase.Run(ServicesToRun);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
src/Jackett.Service.Windows/Service.cs
Normal file
29
src/Jackett.Service.Windows/Service.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using Jackett.Server;
|
||||||
|
using System.ServiceProcess;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Jackett.Service.Windows
|
||||||
|
{
|
||||||
|
public class Service : ServiceBase
|
||||||
|
{
|
||||||
|
private CancellationTokenSource tokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
|
protected override void OnStart(string[] args)
|
||||||
|
{
|
||||||
|
CancellationToken token = tokenSource.Token;
|
||||||
|
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
//Registering callback that would cancel downloading
|
||||||
|
token.Register(() => Helper.StopWebHost());
|
||||||
|
Jackett.Server.Program.Main(new string[0]);
|
||||||
|
}, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnStop()
|
||||||
|
{
|
||||||
|
tokenSource.Cancel(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -39,7 +39,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".NET Core", ".NET Core", "{
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Executables", "Executables", "{AA50F785-12B8-4669-8D4F-EAFB49258E60}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Executables", "Executables", "{AA50F785-12B8-4669-8D4F-EAFB49258E60}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Server", "Jackett.Server\Jackett.Server.csproj", "{84182782-EDBC-4342-ADA6-72B7694D0862}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jackett.Server", "Jackett.Server\Jackett.Server.csproj", "{84182782-EDBC-4342-ADA6-72B7694D0862}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jackett.Service.Windows", "Jackett.Service.Windows\Jackett.Service.Windows.csproj", "{45EA874E-4FF6-4D35-AE62-668EDA5E910D}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -87,6 +89,10 @@ Global
|
|||||||
{84182782-EDBC-4342-ADA6-72B7694D0862}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{84182782-EDBC-4342-ADA6-72B7694D0862}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{84182782-EDBC-4342-ADA6-72B7694D0862}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{84182782-EDBC-4342-ADA6-72B7694D0862}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{84182782-EDBC-4342-ADA6-72B7694D0862}.Release|Any CPU.Build.0 = Release|Any CPU
|
{84182782-EDBC-4342-ADA6-72B7694D0862}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{45EA874E-4FF6-4D35-AE62-668EDA5E910D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{45EA874E-4FF6-4D35-AE62-668EDA5E910D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{45EA874E-4FF6-4D35-AE62-668EDA5E910D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{45EA874E-4FF6-4D35-AE62-668EDA5E910D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -105,6 +111,7 @@ Global
|
|||||||
{FF8B9A1B-AE7E-4F14-9C37-DA861D034738} = {AA50F785-12B8-4669-8D4F-EAFB49258E60}
|
{FF8B9A1B-AE7E-4F14-9C37-DA861D034738} = {AA50F785-12B8-4669-8D4F-EAFB49258E60}
|
||||||
{6A06EC9B-AF21-4DE8-9B50-BC7E3C2C78B9} = {AA50F785-12B8-4669-8D4F-EAFB49258E60}
|
{6A06EC9B-AF21-4DE8-9B50-BC7E3C2C78B9} = {AA50F785-12B8-4669-8D4F-EAFB49258E60}
|
||||||
{84182782-EDBC-4342-ADA6-72B7694D0862} = {6A06EC9B-AF21-4DE8-9B50-BC7E3C2C78B9}
|
{84182782-EDBC-4342-ADA6-72B7694D0862} = {6A06EC9B-AF21-4DE8-9B50-BC7E3C2C78B9}
|
||||||
|
{45EA874E-4FF6-4D35-AE62-668EDA5E910D} = {FF8B9A1B-AE7E-4F14-9C37-DA861D034738}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {54BC4102-8B85-49C1-BA12-257D941D1B97}
|
SolutionGuid = {54BC4102-8B85-49C1-BA12-257D941D1B97}
|
||||||
|
Reference in New Issue
Block a user