update .net core startup
This commit is contained in:
parent
3e06bda46b
commit
95341c5c96
|
@ -18,12 +18,13 @@ namespace Emby.Common.Implementations.IO
|
|||
private readonly bool _supportsAsyncFileStreams;
|
||||
private char[] _invalidFileNameChars;
|
||||
private readonly List<IShortcutHandler> _shortcutHandlers = new List<IShortcutHandler>();
|
||||
protected bool EnableFileSystemRequestConcat = true;
|
||||
private bool EnableFileSystemRequestConcat = true;
|
||||
|
||||
public ManagedFileSystem(ILogger logger, bool supportsAsyncFileStreams, bool enableManagedInvalidFileNameChars)
|
||||
public ManagedFileSystem(ILogger logger, bool supportsAsyncFileStreams, bool enableManagedInvalidFileNameChars, bool enableFileSystemRequestConcat)
|
||||
{
|
||||
Logger = logger;
|
||||
_supportsAsyncFileStreams = supportsAsyncFileStreams;
|
||||
EnableFileSystemRequestConcat = enableFileSystemRequestConcat;
|
||||
SetInvalidFileNameChars(enableManagedInvalidFileNameChars);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace Emby.Common.Implementations.IO
|
||||
{
|
||||
public class WindowsFileSystem : ManagedFileSystem
|
||||
{
|
||||
public WindowsFileSystem(ILogger logger)
|
||||
: base(logger, true, true)
|
||||
{
|
||||
EnableFileSystemRequestConcat = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -142,7 +142,7 @@ namespace Emby.Server.Core
|
|||
/// <summary>
|
||||
/// Class CompositionRoot
|
||||
/// </summary>
|
||||
public class ApplicationHost : BaseApplicationHost<ServerApplicationPaths>, IServerApplicationHost, IDependencyContainer
|
||||
public abstract class ApplicationHost : BaseApplicationHost<ServerApplicationPaths>, IServerApplicationHost, IDependencyContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the server configuration manager.
|
||||
|
@ -257,11 +257,9 @@ namespace Emby.Server.Core
|
|||
|
||||
protected IAuthService AuthService { get; private set; }
|
||||
|
||||
private readonly StartupOptions _startupOptions;
|
||||
protected readonly StartupOptions StartupOptions;
|
||||
private readonly string _releaseAssetFilename;
|
||||
|
||||
internal INativeApp NativeApp { get; set; }
|
||||
|
||||
internal IPowerManagement PowerManagement { get; private set; }
|
||||
internal IImageEncoder ImageEncoder { get; private set; }
|
||||
|
||||
|
@ -275,7 +273,6 @@ namespace Emby.Server.Core
|
|||
ILogManager logManager,
|
||||
StartupOptions options,
|
||||
IFileSystem fileSystem,
|
||||
INativeApp nativeApp,
|
||||
IPowerManagement powerManagement,
|
||||
string releaseAssetFilename,
|
||||
IEnvironmentInfo environmentInfo,
|
||||
|
@ -293,11 +290,10 @@ namespace Emby.Server.Core
|
|||
memoryStreamFactory,
|
||||
networkManager)
|
||||
{
|
||||
_startupOptions = options;
|
||||
StartupOptions = options;
|
||||
_certificateGenerator = certificateGenerator;
|
||||
_releaseAssetFilename = releaseAssetFilename;
|
||||
_defaultUserNameFactory = defaultUsernameFactory;
|
||||
NativeApp = nativeApp;
|
||||
PowerManagement = powerManagement;
|
||||
|
||||
ImageEncoder = imageEncoder;
|
||||
|
@ -314,19 +310,11 @@ namespace Emby.Server.Core
|
|||
{
|
||||
get
|
||||
{
|
||||
return _version ?? (_version = GetAssembly(NativeApp.GetType()).GetName().Version);
|
||||
return _version ?? (_version = GetAssembly(GetType()).GetName().Version);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsRunningAsService
|
||||
{
|
||||
get { return NativeApp.IsRunningAsService; }
|
||||
}
|
||||
|
||||
public bool SupportsRunningAsService
|
||||
{
|
||||
get { return NativeApp.SupportsRunningAsService; }
|
||||
}
|
||||
public abstract bool SupportsRunningAsService { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
|
@ -345,19 +333,7 @@ namespace Emby.Server.Core
|
|||
return type.GetTypeInfo().Assembly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance can self restart.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance can self restart; otherwise, <c>false</c>.</value>
|
||||
public override bool CanSelfRestart
|
||||
{
|
||||
get { return NativeApp.CanSelfRestart; }
|
||||
}
|
||||
|
||||
public bool SupportsAutoRunAtStartup
|
||||
{
|
||||
get { return NativeApp.SupportsAutoRunAtStartup; }
|
||||
}
|
||||
public abstract bool SupportsAutoRunAtStartup { get; }
|
||||
|
||||
private void SetBaseExceptionMessage()
|
||||
{
|
||||
|
@ -580,11 +556,11 @@ namespace Emby.Server.Core
|
|||
|
||||
UserRepository = await GetUserRepository().ConfigureAwait(false);
|
||||
|
||||
var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths, NativeApp.GetDbConnector(), MemoryStreamFactory);
|
||||
var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths, GetDbConnector(), MemoryStreamFactory);
|
||||
DisplayPreferencesRepository = displayPreferencesRepo;
|
||||
RegisterSingleInstance(DisplayPreferencesRepository);
|
||||
|
||||
var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager, NativeApp.GetDbConnector(), MemoryStreamFactory);
|
||||
var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager, GetDbConnector(), MemoryStreamFactory);
|
||||
ItemRepository = itemRepo;
|
||||
RegisterSingleInstance(ItemRepository);
|
||||
|
||||
|
@ -707,7 +683,7 @@ namespace Emby.Server.Core
|
|||
EncodingManager = new EncodingManager(FileSystemManager, Logger, MediaEncoder, ChapterManager, LibraryManager);
|
||||
RegisterSingleInstance(EncodingManager);
|
||||
|
||||
var sharingRepo = new SharingRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector());
|
||||
var sharingRepo = new SharingRepository(LogManager, ApplicationPaths, GetDbConnector());
|
||||
await sharingRepo.Initialize().ConfigureAwait(false);
|
||||
RegisterSingleInstance<ISharingManager>(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this));
|
||||
|
||||
|
@ -727,7 +703,7 @@ namespace Emby.Server.Core
|
|||
|
||||
await displayPreferencesRepo.Initialize().ConfigureAwait(false);
|
||||
|
||||
var userDataRepo = new SqliteUserDataRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector());
|
||||
var userDataRepo = new SqliteUserDataRepository(LogManager, ApplicationPaths, GetDbConnector());
|
||||
|
||||
((UserDataManager)UserDataManager).Repository = userDataRepo;
|
||||
await itemRepo.Initialize(userDataRepo).ConfigureAwait(false);
|
||||
|
@ -770,14 +746,16 @@ namespace Emby.Server.Core
|
|||
{
|
||||
var maxConcurrentImageProcesses = Math.Max(Environment.ProcessorCount, 4);
|
||||
|
||||
if (_startupOptions.ContainsOption("-imagethreads"))
|
||||
if (StartupOptions.ContainsOption("-imagethreads"))
|
||||
{
|
||||
int.TryParse(_startupOptions.GetOption("-imagethreads"), NumberStyles.Any, CultureInfo.InvariantCulture, out maxConcurrentImageProcesses);
|
||||
int.TryParse(StartupOptions.GetOption("-imagethreads"), NumberStyles.Any, CultureInfo.InvariantCulture, out maxConcurrentImageProcesses);
|
||||
}
|
||||
|
||||
return new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, ImageEncoder, maxConcurrentImageProcesses, () => LibraryManager, TimerFactory);
|
||||
}
|
||||
|
||||
protected abstract FFMpegInstallInfo GetFfmpegInstallInfo();
|
||||
|
||||
/// <summary>
|
||||
/// Registers the media encoder.
|
||||
/// </summary>
|
||||
|
@ -787,8 +765,8 @@ namespace Emby.Server.Core
|
|||
string encoderPath = null;
|
||||
string probePath = null;
|
||||
|
||||
var info = await new FFMpegLoader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, NativeApp.GetFfmpegInstallInfo())
|
||||
.GetFFMpegInfo(_startupOptions, progress).ConfigureAwait(false);
|
||||
var info = await new FFMpegLoader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, GetFfmpegInstallInfo())
|
||||
.GetFFMpegInfo(StartupOptions, progress).ConfigureAwait(false);
|
||||
|
||||
encoderPath = info.EncoderPath;
|
||||
probePath = info.ProbePath;
|
||||
|
@ -825,7 +803,7 @@ namespace Emby.Server.Core
|
|||
/// <returns>Task{IUserRepository}.</returns>
|
||||
private async Task<IUserRepository> GetUserRepository()
|
||||
{
|
||||
var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer, NativeApp.GetDbConnector(), MemoryStreamFactory);
|
||||
var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer, GetDbConnector(), MemoryStreamFactory);
|
||||
|
||||
await repo.Initialize().ConfigureAwait(false);
|
||||
|
||||
|
@ -838,7 +816,7 @@ namespace Emby.Server.Core
|
|||
/// <returns>Task{IUserRepository}.</returns>
|
||||
private async Task<IFileOrganizationRepository> GetFileOrganizationRepository()
|
||||
{
|
||||
var repo = new SqliteFileOrganizationRepository(LogManager, ServerConfigurationManager.ApplicationPaths, NativeApp.GetDbConnector());
|
||||
var repo = new SqliteFileOrganizationRepository(LogManager, ServerConfigurationManager.ApplicationPaths, GetDbConnector());
|
||||
|
||||
await repo.Initialize().ConfigureAwait(false);
|
||||
|
||||
|
@ -847,7 +825,7 @@ namespace Emby.Server.Core
|
|||
|
||||
private async Task<IAuthenticationRepository> GetAuthenticationRepository()
|
||||
{
|
||||
var repo = new AuthenticationRepository(LogManager, ServerConfigurationManager.ApplicationPaths, NativeApp.GetDbConnector());
|
||||
var repo = new AuthenticationRepository(LogManager, ServerConfigurationManager.ApplicationPaths, GetDbConnector());
|
||||
|
||||
await repo.Initialize().ConfigureAwait(false);
|
||||
|
||||
|
@ -856,7 +834,7 @@ namespace Emby.Server.Core
|
|||
|
||||
private async Task<IActivityRepository> GetActivityLogRepository()
|
||||
{
|
||||
var repo = new ActivityRepository(LogManager, ServerConfigurationManager.ApplicationPaths, NativeApp.GetDbConnector());
|
||||
var repo = new ActivityRepository(LogManager, ServerConfigurationManager.ApplicationPaths, GetDbConnector());
|
||||
|
||||
await repo.Initialize().ConfigureAwait(false);
|
||||
|
||||
|
@ -865,7 +843,7 @@ namespace Emby.Server.Core
|
|||
|
||||
private async Task<ISyncRepository> GetSyncRepository()
|
||||
{
|
||||
var repo = new SyncRepository(LogManager, JsonSerializer, ServerConfigurationManager.ApplicationPaths, NativeApp.GetDbConnector());
|
||||
var repo = new SyncRepository(LogManager, JsonSerializer, ServerConfigurationManager.ApplicationPaths, GetDbConnector());
|
||||
|
||||
await repo.Initialize().ConfigureAwait(false);
|
||||
|
||||
|
@ -877,7 +855,7 @@ namespace Emby.Server.Core
|
|||
/// </summary>
|
||||
private async Task ConfigureNotificationsRepository()
|
||||
{
|
||||
var repo = new SqliteNotificationsRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector());
|
||||
var repo = new SqliteNotificationsRepository(LogManager, ApplicationPaths, GetDbConnector());
|
||||
|
||||
await repo.Initialize().ConfigureAwait(false);
|
||||
|
||||
|
@ -1123,24 +1101,12 @@ namespace Emby.Server.Core
|
|||
Logger.ErrorException("Error sending server restart notification", ex);
|
||||
}
|
||||
|
||||
Logger.Info("Calling NativeApp.Restart");
|
||||
Logger.Info("Calling RestartInternal");
|
||||
|
||||
NativeApp.Restart(_startupOptions);
|
||||
RestartInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance can self update.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance can self update; otherwise, <c>false</c>.</value>
|
||||
public override bool CanSelfUpdate
|
||||
{
|
||||
get
|
||||
{
|
||||
#pragma warning disable 162
|
||||
return NativeApp.CanSelfUpdate;
|
||||
#pragma warning restore 162
|
||||
}
|
||||
}
|
||||
protected abstract void RestartInternal();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the composable part assemblies.
|
||||
|
@ -1196,14 +1162,16 @@ namespace Emby.Server.Core
|
|||
// Xbmc
|
||||
list.Add(GetAssembly(typeof(ArtistNfoProvider)));
|
||||
|
||||
list.AddRange(NativeApp.GetAssembliesWithParts());
|
||||
list.AddRange(GetAssembliesWithPartsInternal());
|
||||
|
||||
// Include composable parts in the running assembly
|
||||
list.Add(GetAssembly(GetType()));
|
||||
list.Add(GetAssembly(typeof(ApplicationHost)));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
protected abstract List<Assembly> GetAssembliesWithPartsInternal();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin assemblies.
|
||||
/// </summary>
|
||||
|
@ -1280,7 +1248,7 @@ namespace Emby.Server.Core
|
|||
EncoderLocationType = MediaEncoder.EncoderLocationType,
|
||||
SystemArchitecture = EnvironmentInfo.SystemArchitecture,
|
||||
SystemUpdateLevel = ConfigurationManager.CommonConfiguration.SystemUpdateLevel,
|
||||
PackageName = _startupOptions.GetOption("-package")
|
||||
PackageName = StartupOptions.GetOption("-package")
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1456,9 +1424,11 @@ namespace Emby.Server.Core
|
|||
Logger.ErrorException("Error sending server shutdown notification", ex);
|
||||
}
|
||||
|
||||
NativeApp.Shutdown();
|
||||
ShutdownInternal();
|
||||
}
|
||||
|
||||
protected abstract void ShutdownInternal();
|
||||
|
||||
/// <summary>
|
||||
/// Registers the server with administrator access.
|
||||
/// </summary>
|
||||
|
@ -1468,7 +1438,7 @@ namespace Emby.Server.Core
|
|||
|
||||
try
|
||||
{
|
||||
NativeApp.AuthorizeServer(
|
||||
AuthorizeServer(
|
||||
UdpServerEntryPoint.PortNumber,
|
||||
ServerConfigurationManager.Configuration.HttpServerPortNumber,
|
||||
ServerConfigurationManager.Configuration.HttpsPortNumber,
|
||||
|
@ -1481,6 +1451,9 @@ namespace Emby.Server.Core
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory);
|
||||
protected abstract IDbConnector GetDbConnector();
|
||||
|
||||
public event EventHandler HasUpdateAvailableChanged;
|
||||
|
||||
private bool _hasUpdateAvailable;
|
||||
|
@ -1551,10 +1524,12 @@ namespace Emby.Server.Core
|
|||
{
|
||||
if (SupportsAutoRunAtStartup)
|
||||
{
|
||||
NativeApp.ConfigureAutoRun(autorun);
|
||||
ConfigureAutoRunInternal(autorun);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void ConfigureAutoRunInternal(bool autorun);
|
||||
|
||||
/// <summary>
|
||||
/// This returns localhost in the case of no external dns, and the hostname if the
|
||||
/// dns is prefixed with a valid Uri prefix.
|
||||
|
@ -1578,16 +1553,15 @@ namespace Emby.Server.Core
|
|||
}
|
||||
}
|
||||
|
||||
public void LaunchUrl(string url)
|
||||
{
|
||||
NativeApp.LaunchUrl(url);
|
||||
}
|
||||
public abstract void LaunchUrl(string url);
|
||||
|
||||
public void EnableLoopback(string appName)
|
||||
{
|
||||
NativeApp.EnableLoopback(appName);
|
||||
EnableLoopbackInternal(appName);
|
||||
}
|
||||
|
||||
protected abstract void EnableLoopbackInternal(string appName);
|
||||
|
||||
private void RegisterModules()
|
||||
{
|
||||
var moduleTypes = GetExportTypes<IDependencyModule>();
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Emby.Server.Core;
|
||||
using Emby.Server.Core.Data;
|
||||
using Emby.Server.Core.FFMpeg;
|
||||
|
||||
namespace Emby.Server.Core
|
||||
{
|
||||
public interface INativeApp
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the assemblies with parts.
|
||||
/// </summary>
|
||||
/// <returns>List<Assembly>.</returns>
|
||||
List<Assembly> GetAssembliesWithParts();
|
||||
|
||||
/// <summary>
|
||||
/// Authorizes the server.
|
||||
/// </summary>
|
||||
void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether [supports running as service].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [supports running as service]; otherwise, <c>false</c>.</value>
|
||||
bool SupportsRunningAsService { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is running as service.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is running as service; otherwise, <c>false</c>.</value>
|
||||
bool IsRunningAsService { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance can self restart.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance can self restart; otherwise, <c>false</c>.</value>
|
||||
bool CanSelfRestart { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether [supports autorun at startup].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [supports autorun at startup]; otherwise, <c>false</c>.</value>
|
||||
bool SupportsAutoRunAtStartup { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance can self update.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance can self update; otherwise, <c>false</c>.</value>
|
||||
bool CanSelfUpdate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Shutdowns this instance.
|
||||
/// </summary>
|
||||
void Shutdown();
|
||||
|
||||
/// <summary>
|
||||
/// Restarts this instance.
|
||||
/// </summary>
|
||||
void Restart(StartupOptions startupOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Configures the automatic run.
|
||||
/// </summary>
|
||||
/// <param name="autorun">if set to <c>true</c> [autorun].</param>
|
||||
void ConfigureAutoRun(bool autorun);
|
||||
|
||||
FFMpegInstallInfo GetFfmpegInstallInfo();
|
||||
|
||||
void LaunchUrl(string url);
|
||||
|
||||
IDbConnector GetDbConnector();
|
||||
|
||||
void EnableLoopback(string appName);
|
||||
}
|
||||
}
|
|
@ -106,7 +106,7 @@
|
|||
<Compile Include="..\SharedVersion.cs">
|
||||
<Link>Properties\SharedVersion.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Native\MonoApp.cs" />
|
||||
<Compile Include="MonoAppHost.cs" />
|
||||
<Compile Include="Native\DbConnector.cs" />
|
||||
<Compile Include="Native\MonoFileSystem.cs" />
|
||||
<Compile Include="Native\PowerManagement.cs" />
|
||||
|
|
139
MediaBrowser.Server.Mono/MonoAppHost.cs
Normal file
139
MediaBrowser.Server.Mono/MonoAppHost.cs
Normal file
|
@ -0,0 +1,139 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Emby.Server.Core;
|
||||
using Emby.Server.Core.Data;
|
||||
using Emby.Server.Core.FFMpeg;
|
||||
using MediaBrowser.IsoMounter;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.System;
|
||||
using MediaBrowser.Server.Mono.Native;
|
||||
|
||||
namespace MediaBrowser.Server.Mono
|
||||
{
|
||||
public class MonoAppHost : ApplicationHost
|
||||
{
|
||||
public MonoAppHost(ServerApplicationPaths applicationPaths, ILogManager logManager, StartupOptions options, IFileSystem fileSystem, IPowerManagement powerManagement, string releaseAssetFilename, IEnvironmentInfo environmentInfo, MediaBrowser.Controller.Drawing.IImageEncoder imageEncoder, ISystemEvents systemEvents, IMemoryStreamFactory memoryStreamFactory, MediaBrowser.Common.Net.INetworkManager networkManager, Action<string, string> certificateGenerator, Func<string> defaultUsernameFactory) : base(applicationPaths, logManager, options, fileSystem, powerManagement, releaseAssetFilename, environmentInfo, imageEncoder, systemEvents, memoryStreamFactory, networkManager, certificateGenerator, defaultUsernameFactory)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanSelfRestart
|
||||
{
|
||||
get
|
||||
{
|
||||
// A restart script must be provided
|
||||
return StartupOptions.ContainsOption("-restartpath");
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanSelfUpdate
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override FFMpegInstallInfo GetFfmpegInstallInfo()
|
||||
{
|
||||
var info = new FFMpegInstallInfo();
|
||||
|
||||
// Windows builds: http://ffmpeg.zeranoe.com/builds/
|
||||
// Linux builds: http://johnvansickle.com/ffmpeg/
|
||||
// OS X builds: http://ffmpegmac.net/
|
||||
// OS X x64: http://www.evermeet.cx/ffmpeg/
|
||||
|
||||
var environment = (MonoEnvironmentInfo) EnvironmentInfo;
|
||||
|
||||
if (environment.IsBsd)
|
||||
{
|
||||
|
||||
}
|
||||
else if (environment.OperatingSystem == Model.System.OperatingSystem.Linux)
|
||||
{
|
||||
info.ArchiveType = "7z";
|
||||
info.Version = "20160215";
|
||||
}
|
||||
|
||||
// No version available - user requirement
|
||||
info.DownloadUrls = new string[] { };
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
protected override void RestartInternal()
|
||||
{
|
||||
MainClass.Restart(StartupOptions);
|
||||
}
|
||||
|
||||
protected override List<Assembly> GetAssembliesWithPartsInternal()
|
||||
{
|
||||
var list = new List<Assembly>();
|
||||
|
||||
list.Add(GetType().Assembly);
|
||||
list.AddRange(GetLinuxAssemblies());
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private IEnumerable<Assembly> GetLinuxAssemblies()
|
||||
{
|
||||
var list = new List<Assembly>();
|
||||
|
||||
list.Add(typeof(LinuxIsoManager).Assembly);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override void ShutdownInternal()
|
||||
{
|
||||
MainClass.Shutdown();
|
||||
}
|
||||
|
||||
protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override IDbConnector GetDbConnector()
|
||||
{
|
||||
return new DbConnector(Logger);
|
||||
}
|
||||
|
||||
protected override void ConfigureAutoRunInternal(bool autorun)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void LaunchUrl(string url)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override void EnableLoopbackInternal(string appName)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool SupportsRunningAsService
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool SupportsAutoRunAtStartup
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool IsRunningAsService
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.IsoMounter;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Server.Startup.Common;
|
||||
using Mono.Unix.Native;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using Emby.Common.Implementations.Networking;
|
||||
using Emby.Server.Core;
|
||||
using Emby.Server.Core.Data;
|
||||
using Emby.Server.Core.FFMpeg;
|
||||
using MediaBrowser.Model.System;
|
||||
|
||||
namespace MediaBrowser.Server.Mono.Native
|
||||
{
|
||||
public class MonoApp : INativeApp
|
||||
{
|
||||
protected StartupOptions StartupOptions { get; private set; }
|
||||
protected ILogger Logger { get; private set; }
|
||||
private readonly MonoEnvironmentInfo _environment;
|
||||
|
||||
public MonoApp(StartupOptions startupOptions, ILogger logger, MonoEnvironmentInfo environment)
|
||||
{
|
||||
StartupOptions = startupOptions;
|
||||
Logger = logger;
|
||||
_environment = environment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shutdowns this instance.
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
MainClass.Shutdown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this instance [can self restart].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance can self restart; otherwise, <c>false</c>.</value>
|
||||
public bool CanSelfRestart
|
||||
{
|
||||
get
|
||||
{
|
||||
// A restart script must be provided
|
||||
return StartupOptions.ContainsOption("-restartpath");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restarts this instance.
|
||||
/// </summary>
|
||||
public void Restart(StartupOptions startupOptions)
|
||||
{
|
||||
MainClass.Restart(startupOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance can self update.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance can self update; otherwise, <c>false</c>.</value>
|
||||
public bool CanSelfUpdate
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool SupportsAutoRunAtStartup
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public List<Assembly> GetAssembliesWithParts()
|
||||
{
|
||||
var list = new List<Assembly>();
|
||||
|
||||
list.Add(GetType().Assembly);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private IEnumerable<Assembly> GetLinuxAssemblies()
|
||||
{
|
||||
var list = new List<Assembly>();
|
||||
|
||||
//list.Add(typeof(LinuxIsoManager).Assembly);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public void AuthorizeServer(int udpPort, int httpServerPort, int httpsPort, string applicationPath, string tempDirectory)
|
||||
{
|
||||
}
|
||||
|
||||
public bool SupportsRunningAsService
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRunningAsService
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void ConfigureAutoRun(bool autorun)
|
||||
{
|
||||
}
|
||||
|
||||
public INetworkManager CreateNetworkManager(ILogger logger)
|
||||
{
|
||||
return new NetworkManager(logger);
|
||||
}
|
||||
|
||||
public FFMpegInstallInfo GetFfmpegInstallInfo()
|
||||
{
|
||||
var info = new FFMpegInstallInfo();
|
||||
|
||||
// Windows builds: http://ffmpeg.zeranoe.com/builds/
|
||||
// Linux builds: http://johnvansickle.com/ffmpeg/
|
||||
// OS X builds: http://ffmpegmac.net/
|
||||
// OS X x64: http://www.evermeet.cx/ffmpeg/
|
||||
|
||||
if (_environment.IsBsd)
|
||||
{
|
||||
|
||||
}
|
||||
else if (_environment.OperatingSystem == Model.System.OperatingSystem.Linux)
|
||||
{
|
||||
info.ArchiveType = "7z";
|
||||
info.Version = "20160215";
|
||||
}
|
||||
|
||||
// No version available - user requirement
|
||||
info.DownloadUrls = new string[] { };
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public void LaunchUrl(string url)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IDbConnector GetDbConnector()
|
||||
{
|
||||
return new DbConnector(Logger);
|
||||
}
|
||||
|
||||
public void EnableLoopback(string appName)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ namespace MediaBrowser.Server.Mono.Native
|
|||
{
|
||||
public class MonoFileSystem : ManagedFileSystem
|
||||
{
|
||||
public MonoFileSystem(ILogger logger, bool supportsAsyncFileStreams, bool enableManagedInvalidFileNameChars) : base(logger, supportsAsyncFileStreams, enableManagedInvalidFileNameChars)
|
||||
public MonoFileSystem(ILogger logger, bool supportsAsyncFileStreams, bool enableManagedInvalidFileNameChars) : base(logger, supportsAsyncFileStreams, enableManagedInvalidFileNameChars, false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -91,15 +91,12 @@ namespace MediaBrowser.Server.Mono
|
|||
|
||||
var environmentInfo = GetEnvironmentInfo();
|
||||
|
||||
var nativeApp = new MonoApp(options, logManager.GetLogger("App"), environmentInfo);
|
||||
|
||||
var imageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => _appHost.HttpClient, appPaths);
|
||||
|
||||
_appHost = new ApplicationHost(appPaths,
|
||||
_appHost = new MonoAppHost(appPaths,
|
||||
logManager,
|
||||
options,
|
||||
fileSystem,
|
||||
nativeApp,
|
||||
new PowerManagement(),
|
||||
"emby.mono.zip",
|
||||
environmentInfo,
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace MediaBrowser.ServerApplication
|
|||
|
||||
private static ILogger _logger;
|
||||
|
||||
private static bool _isRunningAsService = false;
|
||||
public static bool IsRunningAsService = false;
|
||||
private static bool _canRestartService = false;
|
||||
private static bool _appHostDisposed;
|
||||
|
||||
|
@ -72,9 +72,9 @@ namespace MediaBrowser.ServerApplication
|
|||
public static void Main()
|
||||
{
|
||||
var options = new StartupOptions();
|
||||
_isRunningAsService = options.ContainsOption("-service");
|
||||
IsRunningAsService = options.ContainsOption("-service");
|
||||
|
||||
if (_isRunningAsService)
|
||||
if (IsRunningAsService)
|
||||
{
|
||||
//_canRestartService = CanRestartWindowsService();
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ namespace MediaBrowser.ServerApplication
|
|||
|
||||
var success = SetDllDirectory(architecturePath);
|
||||
|
||||
var appPaths = CreateApplicationPaths(applicationPath, _isRunningAsService);
|
||||
var appPaths = CreateApplicationPaths(applicationPath, IsRunningAsService);
|
||||
|
||||
var logManager = new NlogManager(appPaths.LogDirectoryPath, "server");
|
||||
logManager.ReloadLogger(LogSeverity.Debug);
|
||||
|
@ -148,7 +148,7 @@ namespace MediaBrowser.ServerApplication
|
|||
|
||||
try
|
||||
{
|
||||
RunApplication(appPaths, logManager, _isRunningAsService, options);
|
||||
RunApplication(appPaths, logManager, IsRunningAsService, options);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -204,7 +204,7 @@ namespace MediaBrowser.ServerApplication
|
|||
}
|
||||
}
|
||||
|
||||
if (!_isRunningAsService)
|
||||
if (!IsRunningAsService)
|
||||
{
|
||||
return IsAlreadyRunningAsService(applicationPath);
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ namespace MediaBrowser.ServerApplication
|
|||
{
|
||||
get
|
||||
{
|
||||
if (_isRunningAsService)
|
||||
if (IsRunningAsService)
|
||||
{
|
||||
return _canRestartService;
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ namespace MediaBrowser.ServerApplication
|
|||
return false;
|
||||
#endif
|
||||
|
||||
if (_isRunningAsService)
|
||||
if (IsRunningAsService)
|
||||
{
|
||||
return _canRestartService;
|
||||
}
|
||||
|
@ -317,22 +317,16 @@ namespace MediaBrowser.ServerApplication
|
|||
/// <param name="options">The options.</param>
|
||||
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, bool runService, StartupOptions options)
|
||||
{
|
||||
var fileSystem = new WindowsFileSystem(logManager.GetLogger("FileSystem"));
|
||||
var fileSystem = new ManagedFileSystem(logManager.GetLogger("FileSystem"), true, true, true);
|
||||
fileSystem.AddShortcutHandler(new LnkShortcutHandler());
|
||||
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
|
||||
|
||||
var nativeApp = new WindowsApp(fileSystem, _logger)
|
||||
{
|
||||
IsRunningAsService = runService
|
||||
};
|
||||
|
||||
var imageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => _appHost.HttpClient, appPaths);
|
||||
|
||||
_appHost = new ApplicationHost(appPaths,
|
||||
_appHost = new WindowsAppHost(appPaths,
|
||||
logManager,
|
||||
options,
|
||||
fileSystem,
|
||||
nativeApp,
|
||||
new PowerManagement(),
|
||||
"emby.windows.zip",
|
||||
new EnvironmentInfo(),
|
||||
|
@ -440,7 +434,7 @@ namespace MediaBrowser.ServerApplication
|
|||
|
||||
public static void Invoke(Action action)
|
||||
{
|
||||
if (_isRunningAsService)
|
||||
if (IsRunningAsService)
|
||||
{
|
||||
action();
|
||||
}
|
||||
|
@ -578,7 +572,7 @@ namespace MediaBrowser.ServerApplication
|
|||
/// <param name="e">The <see cref="SessionEndingEventArgs"/> instance containing the event data.</param>
|
||||
static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
|
||||
{
|
||||
if (e.Reason == SessionEndReasons.SystemShutdown || !_isRunningAsService)
|
||||
if (e.Reason == SessionEndReasons.SystemShutdown || !IsRunningAsService)
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
@ -595,7 +589,7 @@ namespace MediaBrowser.ServerApplication
|
|||
|
||||
new UnhandledExceptionWriter(_appHost.ServerConfigurationManager.ApplicationPaths, _logger, _appHost.LogManager).Log(exception);
|
||||
|
||||
if (!_isRunningAsService)
|
||||
if (!IsRunningAsService)
|
||||
{
|
||||
MessageBox.Show("Unhandled exception: " + exception.Message);
|
||||
}
|
||||
|
@ -623,7 +617,7 @@ namespace MediaBrowser.ServerApplication
|
|||
// Update is there - execute update
|
||||
try
|
||||
{
|
||||
var serviceName = _isRunningAsService ? BackgroundService.GetExistingServiceName() : string.Empty;
|
||||
var serviceName = IsRunningAsService ? BackgroundService.GetExistingServiceName() : string.Empty;
|
||||
new ApplicationUpdater().UpdateApplication(appPaths, updateArchive, logger, serviceName);
|
||||
|
||||
// And just let the app exit so it can update
|
||||
|
@ -642,7 +636,7 @@ namespace MediaBrowser.ServerApplication
|
|||
|
||||
public static void Shutdown()
|
||||
{
|
||||
if (_isRunningAsService)
|
||||
if (IsRunningAsService)
|
||||
{
|
||||
ShutdownWindowsService();
|
||||
}
|
||||
|
@ -658,7 +652,7 @@ namespace MediaBrowser.ServerApplication
|
|||
{
|
||||
DisposeAppHost();
|
||||
|
||||
if (_isRunningAsService)
|
||||
if (IsRunningAsService)
|
||||
{
|
||||
RestartWindowsService();
|
||||
}
|
||||
|
|
|
@ -138,7 +138,6 @@
|
|||
<Compile Include="Native\PowerManagement.cs" />
|
||||
<Compile Include="Native\Standby.cs" />
|
||||
<Compile Include="Native\ServerAuthorization.cs" />
|
||||
<Compile Include="Native\WindowsApp.cs" />
|
||||
<Compile Include="Networking\NativeMethods.cs" />
|
||||
<Compile Include="Networking\NetworkManager.cs" />
|
||||
<Compile Include="Networking\NetworkShares.cs" />
|
||||
|
@ -156,6 +155,7 @@
|
|||
<DependentUpon>SplashForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Updates\ApplicationUpdater.cs" />
|
||||
<Compile Include="WindowsAppHost.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
|
|
|
@ -1,131 +1,31 @@
|
|||
using System;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Server.Startup.Common;
|
||||
using MediaBrowser.ServerApplication.Networking;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using Emby.Server.Core;
|
||||
using Emby.Server.Core.Data;
|
||||
using Emby.Server.Core.FFMpeg;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.System;
|
||||
using MediaBrowser.ServerApplication.Native;
|
||||
|
||||
namespace MediaBrowser.ServerApplication.Native
|
||||
namespace MediaBrowser.ServerApplication
|
||||
{
|
||||
public class WindowsApp : INativeApp
|
||||
public class WindowsAppHost : ApplicationHost
|
||||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public WindowsApp(IFileSystem fileSystem, ILogger logger)
|
||||
public WindowsAppHost(ServerApplicationPaths applicationPaths, ILogManager logManager, StartupOptions options, IFileSystem fileSystem, IPowerManagement powerManagement, string releaseAssetFilename, IEnvironmentInfo environmentInfo, MediaBrowser.Controller.Drawing.IImageEncoder imageEncoder, ISystemEvents systemEvents, IMemoryStreamFactory memoryStreamFactory, MediaBrowser.Common.Net.INetworkManager networkManager, Action<string, string> certificateGenerator, Func<string> defaultUsernameFactory)
|
||||
: base(applicationPaths, logManager, options, fileSystem, powerManagement, releaseAssetFilename, environmentInfo, imageEncoder, systemEvents, memoryStreamFactory, networkManager, certificateGenerator, defaultUsernameFactory)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public List<Assembly> GetAssembliesWithParts()
|
||||
public override bool IsRunningAsService
|
||||
{
|
||||
var list = new List<Assembly>();
|
||||
|
||||
if (!System.Environment.Is64BitProcess)
|
||||
{
|
||||
//list.Add(typeof(PismoIsoManager).Assembly);
|
||||
get { return MainStartup.IsRunningAsService; }
|
||||
}
|
||||
|
||||
list.Add(GetType().Assembly);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public void AuthorizeServer(int udpPort, int httpServerPort, int httpsPort, string applicationPath, string tempDirectory)
|
||||
{
|
||||
ServerAuthorization.AuthorizeServer(udpPort, httpServerPort, httpsPort, applicationPath, tempDirectory);
|
||||
}
|
||||
|
||||
public bool SupportsLibraryMonitor
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public bool SupportsRunningAsService
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRunningAsService
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool CanSelfRestart
|
||||
{
|
||||
get
|
||||
{
|
||||
return MainStartup.CanSelfRestart;
|
||||
}
|
||||
}
|
||||
|
||||
public bool SupportsAutoRunAtStartup
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanSelfUpdate
|
||||
{
|
||||
get
|
||||
{
|
||||
return MainStartup.CanSelfUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
MainStartup.Shutdown();
|
||||
}
|
||||
|
||||
public void Restart(StartupOptions startupOptions)
|
||||
{
|
||||
MainStartup.Restart();
|
||||
}
|
||||
|
||||
public void ConfigureAutoRun(bool autorun)
|
||||
{
|
||||
var shortcutPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.StartMenu), "Emby", "Emby Server.lnk");
|
||||
|
||||
var startupPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Startup);
|
||||
|
||||
if (autorun)
|
||||
{
|
||||
//Copy our shortut into the startup folder for this user
|
||||
var targetPath = Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk");
|
||||
_fileSystem.CreateDirectory(Path.GetDirectoryName(targetPath));
|
||||
File.Copy(shortcutPath, targetPath, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Remove our shortcut from the startup folder for this user
|
||||
_fileSystem.DeleteFile(Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk"));
|
||||
}
|
||||
}
|
||||
|
||||
public INetworkManager CreateNetworkManager(ILogger logger)
|
||||
{
|
||||
return new NetworkManager(logger);
|
||||
}
|
||||
|
||||
public FFMpegInstallInfo GetFfmpegInstallInfo()
|
||||
protected override FFMpegInstallInfo GetFfmpegInstallInfo()
|
||||
{
|
||||
var info = new FFMpegInstallInfo();
|
||||
|
||||
|
@ -136,7 +36,61 @@ namespace MediaBrowser.ServerApplication.Native
|
|||
return info;
|
||||
}
|
||||
|
||||
public void LaunchUrl(string url)
|
||||
protected override void RestartInternal()
|
||||
{
|
||||
MainStartup.Restart();
|
||||
}
|
||||
|
||||
protected override List<Assembly> GetAssembliesWithPartsInternal()
|
||||
{
|
||||
var list = new List<Assembly>();
|
||||
|
||||
if (!Environment.Is64BitProcess)
|
||||
{
|
||||
//list.Add(typeof(PismoIsoManager).Assembly);
|
||||
}
|
||||
|
||||
list.Add(GetType().Assembly);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override void ShutdownInternal()
|
||||
{
|
||||
MainStartup.Shutdown();
|
||||
}
|
||||
|
||||
protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory)
|
||||
{
|
||||
ServerAuthorization.AuthorizeServer(udpPort, httpServerPort, httpsServerPort, applicationPath, tempDirectory);
|
||||
}
|
||||
|
||||
protected override IDbConnector GetDbConnector()
|
||||
{
|
||||
return new DbConnector(Logger);
|
||||
}
|
||||
|
||||
protected override void ConfigureAutoRunInternal(bool autorun)
|
||||
{
|
||||
var shortcutPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.StartMenu), "Emby", "Emby Server.lnk");
|
||||
|
||||
var startupPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Startup);
|
||||
|
||||
if (autorun)
|
||||
{
|
||||
//Copy our shortut into the startup folder for this user
|
||||
var targetPath = Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk");
|
||||
FileSystemManager.CreateDirectory(Path.GetDirectoryName(targetPath));
|
||||
File.Copy(shortcutPath, targetPath, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Remove our shortcut from the startup folder for this user
|
||||
FileSystemManager.DeleteFile(Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk"));
|
||||
}
|
||||
}
|
||||
|
||||
public override void LaunchUrl(string url)
|
||||
{
|
||||
var process = new Process
|
||||
{
|
||||
|
@ -156,32 +110,54 @@ namespace MediaBrowser.ServerApplication.Native
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error launching url: {0}", ex, url);
|
||||
Logger.ErrorException("Error launching url: {0}", ex, url);
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public IDbConnector GetDbConnector()
|
||||
{
|
||||
return new DbConnector(_logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes the exited.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender.</param>
|
||||
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
|
||||
private static void ProcessExited(object sender, EventArgs e)
|
||||
{
|
||||
((Process)sender).Dispose();
|
||||
}
|
||||
|
||||
public void EnableLoopback(string appName)
|
||||
protected override void EnableLoopbackInternal(string appName)
|
||||
{
|
||||
LoopUtil.Run(appName);
|
||||
}
|
||||
|
||||
public override bool SupportsRunningAsService
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanSelfRestart
|
||||
{
|
||||
get
|
||||
{
|
||||
return MainStartup.CanSelfRestart;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool SupportsAutoRunAtStartup
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanSelfUpdate
|
||||
{
|
||||
get
|
||||
{
|
||||
return MainStartup.CanSelfUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
public bool PortsRequireAuthorization(string applicationPath)
|
||||
{
|
||||
var appNameSrch = Path.GetFileName(applicationPath);
|
||||
|
@ -209,7 +185,7 @@ namespace MediaBrowser.ServerApplication.Native
|
|||
|
||||
if (data.IndexOf("Block", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
_logger.Info("Found potential windows firewall rule blocking Emby Server: " + data);
|
||||
Logger.Info("Found potential windows firewall rule blocking Emby Server: " + data);
|
||||
}
|
||||
|
||||
//var parts = data.Split('\n');
|
||||
|
@ -220,7 +196,7 @@ namespace MediaBrowser.ServerApplication.Native
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error querying windows firewall", ex);
|
||||
Logger.ErrorException("Error querying windows firewall", ex);
|
||||
|
||||
// Hate having to do this
|
||||
try
|
||||
|
@ -229,12 +205,13 @@ namespace MediaBrowser.ServerApplication.Native
|
|||
}
|
||||
catch (Exception ex1)
|
||||
{
|
||||
_logger.ErrorException("Error killing process", ex1);
|
||||
Logger.ErrorException("Error killing process", ex1);
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
47
src/Emby.Server/ApplicationPathHelper.cs
Normal file
47
src/Emby.Server/ApplicationPathHelper.cs
Normal file
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Emby.Server
|
||||
{
|
||||
public class ApplicationPathHelper
|
||||
{
|
||||
public static string GetProgramDataPath(string applicationPath)
|
||||
{
|
||||
var useDebugPath = false;
|
||||
|
||||
#if DEBUG
|
||||
useDebugPath = true;
|
||||
#endif
|
||||
|
||||
var programDataPath = useDebugPath ?
|
||||
"programdata" :
|
||||
"programdata";
|
||||
|
||||
programDataPath = programDataPath
|
||||
.Replace('/', Path.DirectorySeparatorChar)
|
||||
.Replace('\\', Path.DirectorySeparatorChar);
|
||||
|
||||
// If it's a relative path, e.g. "..\"
|
||||
if (!Path.IsPathRooted(programDataPath))
|
||||
{
|
||||
var path = Path.GetDirectoryName(applicationPath);
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
throw new Exception("Unable to determine running assembly location");
|
||||
}
|
||||
|
||||
programDataPath = Path.Combine(path, programDataPath);
|
||||
|
||||
programDataPath = Path.GetFullPath(programDataPath);
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(programDataPath);
|
||||
|
||||
return programDataPath;
|
||||
}
|
||||
}
|
||||
}
|
107
src/Emby.Server/CoreAppHost.cs
Normal file
107
src/Emby.Server/CoreAppHost.cs
Normal file
|
@ -0,0 +1,107 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Emby.Server.Core;
|
||||
using Emby.Server.Core.Data;
|
||||
using Emby.Server.Core.FFMpeg;
|
||||
using Emby.Server.Data;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.System;
|
||||
|
||||
namespace Emby.Server
|
||||
{
|
||||
public class CoreAppHost : ApplicationHost
|
||||
{
|
||||
public CoreAppHost(ServerApplicationPaths applicationPaths, ILogManager logManager, StartupOptions options, IFileSystem fileSystem, IPowerManagement powerManagement, string releaseAssetFilename, IEnvironmentInfo environmentInfo, MediaBrowser.Controller.Drawing.IImageEncoder imageEncoder, ISystemEvents systemEvents, IMemoryStreamFactory memoryStreamFactory, MediaBrowser.Common.Net.INetworkManager networkManager, Action<string, string> certificateGenerator, Func<string> defaultUsernameFactory)
|
||||
: base(applicationPaths, logManager, options, fileSystem, powerManagement, releaseAssetFilename, environmentInfo, imageEncoder, systemEvents, memoryStreamFactory, networkManager, certificateGenerator, defaultUsernameFactory)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool IsRunningAsService
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
protected override void RestartInternal()
|
||||
{
|
||||
Program.Restart();
|
||||
}
|
||||
|
||||
protected override void ShutdownInternal()
|
||||
{
|
||||
Program.Shutdown();
|
||||
}
|
||||
|
||||
protected override FFMpegInstallInfo GetFfmpegInstallInfo()
|
||||
{
|
||||
var info = new FFMpegInstallInfo();
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
protected override List<Assembly> GetAssembliesWithPartsInternal()
|
||||
{
|
||||
var list = new List<Assembly>();
|
||||
|
||||
list.Add(GetType().GetTypeInfo().Assembly);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IDbConnector GetDbConnector()
|
||||
{
|
||||
return new DbConnector(Logger);
|
||||
}
|
||||
|
||||
protected override void ConfigureAutoRunInternal(bool autorun)
|
||||
{
|
||||
}
|
||||
|
||||
public override void LaunchUrl(string url)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void EnableLoopbackInternal(string appName)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool SupportsRunningAsService
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanSelfRestart
|
||||
{
|
||||
get
|
||||
{
|
||||
return Program.CanSelfRestart;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool SupportsAutoRunAtStartup
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanSelfUpdate
|
||||
{
|
||||
get
|
||||
{
|
||||
return Program.CanSelfUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
src/Emby.Server/CoreSystemEvents.cs
Normal file
11
src/Emby.Server/CoreSystemEvents.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using MediaBrowser.Model.System;
|
||||
|
||||
namespace Emby.Server
|
||||
{
|
||||
public class CoreSystemEvents : ISystemEvents
|
||||
{
|
||||
public event EventHandler Resume;
|
||||
public event EventHandler Suspend;
|
||||
}
|
||||
}
|
52
src/Emby.Server/Data/DbConnector.cs
Normal file
52
src/Emby.Server/Data/DbConnector.cs
Normal file
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using System.Data;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using Emby.Server.Core.Data;
|
||||
using Microsoft.Data.Sqlite;
|
||||
|
||||
namespace Emby.Server.Data
|
||||
{
|
||||
public class DbConnector : IDbConnector
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public DbConnector(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<IDbConnection> Connect(string dbPath, bool isReadOnly, bool enablePooling = false, int? cacheSize = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(dbPath))
|
||||
{
|
||||
throw new ArgumentNullException("dbPath");
|
||||
}
|
||||
|
||||
//SQLiteConnection.SetMemoryStatus(false);
|
||||
|
||||
var connectionstr = new SqliteConnectionStringBuilder
|
||||
{
|
||||
//PageSize = 4096,
|
||||
//CacheSize = cacheSize ?? 2000,
|
||||
//SyncMode = SynchronizationModes.Normal,
|
||||
DataSource = dbPath,
|
||||
//JournalMode = SQLiteJournalModeEnum.Wal,
|
||||
|
||||
// This is causing crashing under linux
|
||||
//Pooling = enablePooling && Environment.OSVersion.Platform == PlatformID.Win32NT,
|
||||
//ReadOnly = isReadOnly,
|
||||
Cache = enablePooling ? SqliteCacheMode.Default : SqliteCacheMode.Private,
|
||||
Mode = isReadOnly ? SqliteOpenMode.ReadOnly : SqliteOpenMode.ReadWriteCreate
|
||||
};
|
||||
|
||||
var connectionString = connectionstr.ConnectionString;
|
||||
|
||||
var connection = new SqliteConnection(connectionString);
|
||||
|
||||
await connection.OpenAsync().ConfigureAwait(false);
|
||||
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
}
|
33
src/Emby.Server/IO/MemoryStreamFactory.cs
Normal file
33
src/Emby.Server/IO/MemoryStreamFactory.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using MediaBrowser.Model.IO;
|
||||
|
||||
namespace Emby.Server.IO
|
||||
{
|
||||
public class MemoryStreamFactory : IMemoryStreamFactory
|
||||
{
|
||||
public MemoryStream CreateNew()
|
||||
{
|
||||
return new MemoryStream();
|
||||
}
|
||||
|
||||
public MemoryStream CreateNew(int capacity)
|
||||
{
|
||||
return new MemoryStream(capacity);
|
||||
}
|
||||
|
||||
public MemoryStream CreateNew(byte[] buffer)
|
||||
{
|
||||
return new MemoryStream(buffer);
|
||||
}
|
||||
|
||||
public bool TryGetBuffer(MemoryStream stream, out byte[] buffer)
|
||||
{
|
||||
ArraySegment<byte> arrayBuffer;
|
||||
stream.TryGetBuffer(out arrayBuffer);
|
||||
|
||||
buffer = arrayBuffer.Array;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
15
src/Emby.Server/PowerManagement.cs
Normal file
15
src/Emby.Server/PowerManagement.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using MediaBrowser.Model.System;
|
||||
|
||||
namespace Emby.Server
|
||||
{
|
||||
public class PowerManagement : IPowerManagement
|
||||
{
|
||||
public void PreventSystemStandby()
|
||||
{
|
||||
}
|
||||
|
||||
public void AllowSystemStandby()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,33 +1,24 @@
|
|||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Server.Implementations;
|
||||
using MediaBrowser.Server.Startup.Common;
|
||||
using MediaBrowser.ServerApplication.Native;
|
||||
using MediaBrowser.ServerApplication.Splash;
|
||||
using MediaBrowser.ServerApplication.Updates;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Configuration.Install;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Emby.Common.Implementations.EnvironmentInfo;
|
||||
using Emby.Common.Implementations.IO;
|
||||
using Emby.Common.Implementations.Logging;
|
||||
using Emby.Common.Implementations.Networking;
|
||||
using Emby.Common.Implementations.Security;
|
||||
using Emby.Drawing;
|
||||
using Emby.Server.Core;
|
||||
using Emby.Server.Core.Browser;
|
||||
using Emby.Server.Implementations.IO;
|
||||
using ImageMagickSharp;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Server.Startup.Common.IO;
|
||||
using Emby.Server.IO;
|
||||
|
||||
namespace Emby.Server
|
||||
{
|
||||
|
@ -60,11 +51,11 @@ namespace Emby.Server
|
|||
var currentProcess = Process.GetCurrentProcess();
|
||||
|
||||
var applicationPath = currentProcess.MainModule.FileName;
|
||||
var architecturePath = Path.Combine(Path.GetDirectoryName(applicationPath), Environment.Is64BitProcess ? "x64" : "x86");
|
||||
//var architecturePath = Path.Combine(Path.GetDirectoryName(applicationPath), Environment.Is64BitProcess ? "x64" : "x86");
|
||||
|
||||
Wand.SetMagickCoderModulePath(architecturePath);
|
||||
//Wand.SetMagickCoderModulePath(architecturePath);
|
||||
|
||||
var success = SetDllDirectory(architecturePath);
|
||||
//var success = SetDllDirectory(architecturePath);
|
||||
|
||||
var appPaths = CreateApplicationPaths(applicationPath, _isRunningAsService);
|
||||
|
||||
|
@ -227,31 +218,25 @@ namespace Emby.Server
|
|||
/// <param name="options">The options.</param>
|
||||
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, bool runService, StartupOptions options)
|
||||
{
|
||||
var fileSystem = new WindowsFileSystem(logManager.GetLogger("FileSystem"));
|
||||
fileSystem.AddShortcutHandler(new LnkShortcutHandler());
|
||||
var fileSystem = new ManagedFileSystem(logManager.GetLogger("FileSystem"), true, true, true);
|
||||
|
||||
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
|
||||
|
||||
var nativeApp = new WindowsApp(fileSystem, _logger)
|
||||
{
|
||||
IsRunningAsService = runService
|
||||
};
|
||||
var imageEncoder = new NullImageEncoder();
|
||||
|
||||
var imageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => _appHost.HttpClient, appPaths);
|
||||
|
||||
_appHost = new ApplicationHost(appPaths,
|
||||
_appHost = new CoreAppHost(appPaths,
|
||||
logManager,
|
||||
options,
|
||||
fileSystem,
|
||||
nativeApp,
|
||||
new PowerManagement(),
|
||||
"emby.windows.zip",
|
||||
new EnvironmentInfo(),
|
||||
imageEncoder,
|
||||
new Server.Startup.Common.SystemEvents(logManager.GetLogger("SystemEvents")),
|
||||
new RecyclableMemoryStreamProvider(),
|
||||
new CoreSystemEvents(),
|
||||
new MemoryStreamFactory(),
|
||||
new NetworkManager(logManager.GetLogger("NetworkManager")),
|
||||
GenerateCertificate,
|
||||
() => Environment.UserDomainName);
|
||||
() => "EmbyUser");
|
||||
|
||||
var initProgress = new Progress<double>();
|
||||
|
||||
|
@ -275,12 +260,6 @@ namespace Emby.Server
|
|||
{
|
||||
Task.WaitAll(task);
|
||||
|
||||
task = InstallVcredist2013IfNeeded(_appHost, _logger);
|
||||
Task.WaitAll(task);
|
||||
|
||||
Microsoft.Win32.SystemEvents.SessionEnding += SystemEvents_SessionEnding;
|
||||
Microsoft.Win32.SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
|
||||
|
||||
task = ApplicationTaskCompletionSource.Task;
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
@ -288,15 +267,7 @@ namespace Emby.Server
|
|||
|
||||
private static void GenerateCertificate(string certPath, string certHost)
|
||||
{
|
||||
CertificateGenerator.CreateSelfSignCertificatePfx(certPath, certHost, _logger);
|
||||
}
|
||||
|
||||
static void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
|
||||
{
|
||||
if (e.Reason == SessionSwitchReason.SessionLogon)
|
||||
{
|
||||
BrowserLauncher.OpenDashboard(_appHost);
|
||||
}
|
||||
//CertificateGenerator.CreateSelfSignCertificatePfx(certPath, certHost, _logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -304,11 +275,6 @@ namespace Emby.Server
|
|||
/// </summary>
|
||||
private static void StartService(ILogManager logManager)
|
||||
{
|
||||
var service = new BackgroundService(logManager.GetLogger("Service"));
|
||||
|
||||
service.Disposed += service_Disposed;
|
||||
|
||||
ServiceBase.Run(service);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -329,19 +295,6 @@ namespace Emby.Server
|
|||
DisposeAppHost();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the SessionEnding event of the SystemEvents control.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="SessionEndingEventArgs"/> instance containing the event data.</param>
|
||||
static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
|
||||
{
|
||||
if (e.Reason == SessionEndReasons.SystemShutdown || !_isRunningAsService)
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the UnhandledException event of the CurrentDomain control.
|
||||
/// </summary>
|
||||
|
@ -355,7 +308,7 @@ namespace Emby.Server
|
|||
|
||||
if (!_isRunningAsService)
|
||||
{
|
||||
MessageBox.Show("Unhandled exception: " + exception.Message);
|
||||
ShowMessageBox("Unhandled exception: " + exception.Message);
|
||||
}
|
||||
|
||||
if (!Debugger.IsAttached)
|
||||
|
@ -381,8 +334,8 @@ namespace Emby.Server
|
|||
// Update is there - execute update
|
||||
try
|
||||
{
|
||||
var serviceName = _isRunningAsService ? BackgroundService.GetExistingServiceName() : string.Empty;
|
||||
new ApplicationUpdater().UpdateApplication(appPaths, updateArchive, logger, serviceName);
|
||||
//var serviceName = _isRunningAsService ? BackgroundService.GetExistingServiceName() : string.Empty;
|
||||
//new ApplicationUpdater().UpdateApplication(appPaths, updateArchive, logger, serviceName);
|
||||
|
||||
// And just let the app exit so it can update
|
||||
return true;
|
||||
|
@ -391,13 +344,18 @@ namespace Emby.Server
|
|||
{
|
||||
logger.ErrorException("Error starting updater.", e);
|
||||
|
||||
MessageBox.Show(string.Format("Error attempting to update application.\n\n{0}\n\n{1}", e.GetType().Name, e.Message));
|
||||
ShowMessageBox(string.Format("Error attempting to update application.\n\n{0}\n\n{1}", e.GetType().Name, e.Message));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void ShowMessageBox(string msg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static void Shutdown()
|
||||
{
|
||||
if (_isRunningAsService)
|
||||
|
@ -469,90 +427,6 @@ namespace Emby.Server
|
|||
return false;
|
||||
}
|
||||
|
||||
private static async Task InstallVcredist2013IfNeeded(ApplicationHost appHost, ILogger logger)
|
||||
{
|
||||
// Reference
|
||||
// http://stackoverflow.com/questions/12206314/detect-if-visual-c-redistributable-for-visual-studio-2012-is-installed
|
||||
|
||||
try
|
||||
{
|
||||
var subkey = Environment.Is64BitProcess
|
||||
? "SOFTWARE\\WOW6432Node\\Microsoft\\VisualStudio\\12.0\\VC\\Runtimes\\x64"
|
||||
: "SOFTWARE\\Microsoft\\VisualStudio\\12.0\\VC\\Runtimes\\x86";
|
||||
|
||||
using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default)
|
||||
.OpenSubKey(subkey))
|
||||
{
|
||||
if (ndpKey != null && ndpKey.GetValue("Version") != null)
|
||||
{
|
||||
var installedVersion = ((string)ndpKey.GetValue("Version")).TrimStart('v');
|
||||
if (installedVersion.StartsWith("12", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.ErrorException("Error getting .NET Framework version", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await InstallVcredist2013().ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.ErrorException("Error installing Visual Studio C++ runtime", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async static Task InstallVcredist2013()
|
||||
{
|
||||
var httpClient = _appHost.HttpClient;
|
||||
|
||||
var tmp = await httpClient.GetTempFile(new HttpRequestOptions
|
||||
{
|
||||
Url = GetVcredist2013Url(),
|
||||
Progress = new Progress<double>()
|
||||
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
var exePath = Path.ChangeExtension(tmp, ".exe");
|
||||
File.Copy(tmp, exePath);
|
||||
|
||||
var startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = exePath,
|
||||
|
||||
CreateNoWindow = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
Verb = "runas",
|
||||
ErrorDialog = false
|
||||
};
|
||||
|
||||
_logger.Info("Running {0}", startInfo.FileName);
|
||||
|
||||
using (var process = Process.Start(startInfo))
|
||||
{
|
||||
process.WaitForExit();
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetVcredist2013Url()
|
||||
{
|
||||
if (Environment.Is64BitProcess)
|
||||
{
|
||||
return "https://github.com/MediaBrowser/Emby.Resources/raw/master/vcredist2013/vcredist_x64.exe";
|
||||
}
|
||||
|
||||
// TODO: ARM url - https://github.com/MediaBrowser/Emby.Resources/raw/master/vcredist2013/vcredist_arm.exe
|
||||
|
||||
return "https://github.com/MediaBrowser/Emby.Resources/raw/master/vcredist2013/vcredist_x86.exe";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the error mode.
|
||||
/// </summary>
|
||||
|
|
|
@ -11,7 +11,11 @@
|
|||
"type": "platform",
|
||||
"version": "1.0.1"
|
||||
},
|
||||
"Mono.Nat": "1.0.0-*"
|
||||
"Mono.Nat": "1.0.0-*",
|
||||
"Microsoft.Win32.Registry": "4.0.0",
|
||||
"System.Runtime.Extensions": "4.1.0",
|
||||
"System.Diagnostics.Process": "4.1.0",
|
||||
"Microsoft.Data.SQLite": "1.0.0"
|
||||
},
|
||||
|
||||
"frameworks": {
|
||||
|
|
Loading…
Reference in New Issue
Block a user