diff --git a/Emby.Common.Implementations/IO/ManagedFileSystem.cs b/Emby.Common.Implementations/IO/ManagedFileSystem.cs index 81ca8dcff2..1f0aa55fac 100644 --- a/Emby.Common.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Common.Implementations/IO/ManagedFileSystem.cs @@ -18,12 +18,13 @@ namespace Emby.Common.Implementations.IO private readonly bool _supportsAsyncFileStreams; private char[] _invalidFileNameChars; private readonly List _shortcutHandlers = new List(); - 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); } diff --git a/Emby.Common.Implementations/IO/WindowsFileSystem.cs b/Emby.Common.Implementations/IO/WindowsFileSystem.cs deleted file mode 100644 index 3eafeb2f76..0000000000 --- a/Emby.Common.Implementations/IO/WindowsFileSystem.cs +++ /dev/null @@ -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; - } - } -} diff --git a/Emby.Server.Core/ApplicationHost.cs b/Emby.Server.Core/ApplicationHost.cs index 5c8aea7edf..7f795a68de 100644 --- a/Emby.Server.Core/ApplicationHost.cs +++ b/Emby.Server.Core/ApplicationHost.cs @@ -142,7 +142,7 @@ namespace Emby.Server.Core /// /// Class CompositionRoot /// - public class ApplicationHost : BaseApplicationHost, IServerApplicationHost, IDependencyContainer + public abstract class ApplicationHost : BaseApplicationHost, IServerApplicationHost, IDependencyContainer { /// /// 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; } /// /// Gets the name. @@ -345,19 +333,7 @@ namespace Emby.Server.Core return type.GetTypeInfo().Assembly; } - /// - /// Gets a value indicating whether this instance can self restart. - /// - /// true if this instance can self restart; otherwise, false. - 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(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(); + /// /// Registers the media encoder. /// @@ -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 /// Task{IUserRepository}. private async Task 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 /// Task{IUserRepository}. private async Task 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 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 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 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 /// 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(); } - /// - /// Gets or sets a value indicating whether this instance can self update. - /// - /// true if this instance can self update; otherwise, false. - public override bool CanSelfUpdate - { - get - { -#pragma warning disable 162 - return NativeApp.CanSelfUpdate; -#pragma warning restore 162 - } - } + protected abstract void RestartInternal(); /// /// 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 GetAssembliesWithPartsInternal(); + /// /// Gets the plugin assemblies. /// @@ -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(); + /// /// Registers the server with administrator access. /// @@ -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); + /// /// 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(); diff --git a/Emby.Server.Core/INativeApp.cs b/Emby.Server.Core/INativeApp.cs deleted file mode 100644 index a4e4b32217..0000000000 --- a/Emby.Server.Core/INativeApp.cs +++ /dev/null @@ -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 - { - /// - /// Gets the assemblies with parts. - /// - /// List<Assembly>. - List GetAssembliesWithParts(); - - /// - /// Authorizes the server. - /// - void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory); - - /// - /// Gets a value indicating whether [supports running as service]. - /// - /// true if [supports running as service]; otherwise, false. - bool SupportsRunningAsService { get; } - - /// - /// Gets a value indicating whether this instance is running as service. - /// - /// true if this instance is running as service; otherwise, false. - bool IsRunningAsService { get; } - - /// - /// Gets a value indicating whether this instance can self restart. - /// - /// true if this instance can self restart; otherwise, false. - bool CanSelfRestart { get; } - - /// - /// Gets a value indicating whether [supports autorun at startup]. - /// - /// true if [supports autorun at startup]; otherwise, false. - bool SupportsAutoRunAtStartup { get; } - - /// - /// Gets a value indicating whether this instance can self update. - /// - /// true if this instance can self update; otherwise, false. - bool CanSelfUpdate { get; } - - /// - /// Shutdowns this instance. - /// - void Shutdown(); - - /// - /// Restarts this instance. - /// - void Restart(StartupOptions startupOptions); - - /// - /// Configures the automatic run. - /// - /// if set to true [autorun]. - void ConfigureAutoRun(bool autorun); - - FFMpegInstallInfo GetFfmpegInstallInfo(); - - void LaunchUrl(string url); - - IDbConnector GetDbConnector(); - - void EnableLoopback(string appName); - } -} diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index ca830b2f49..270c43e131 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -106,7 +106,7 @@ Properties\SharedVersion.cs - + diff --git a/MediaBrowser.Server.Mono/MonoAppHost.cs b/MediaBrowser.Server.Mono/MonoAppHost.cs new file mode 100644 index 0000000000..5f0ecde24e --- /dev/null +++ b/MediaBrowser.Server.Mono/MonoAppHost.cs @@ -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 certificateGenerator, Func 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 GetAssembliesWithPartsInternal() + { + var list = new List(); + + list.Add(GetType().Assembly); + list.AddRange(GetLinuxAssemblies()); + + return list; + } + + private IEnumerable GetLinuxAssemblies() + { + var list = new List(); + + 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; + } + } + } +} diff --git a/MediaBrowser.Server.Mono/Native/MonoApp.cs b/MediaBrowser.Server.Mono/Native/MonoApp.cs deleted file mode 100644 index 8257a1b8df..0000000000 --- a/MediaBrowser.Server.Mono/Native/MonoApp.cs +++ /dev/null @@ -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; - } - - /// - /// Shutdowns this instance. - /// - public void Shutdown() - { - MainClass.Shutdown(); - } - - /// - /// Determines whether this instance [can self restart]. - /// - /// true if this instance can self restart; otherwise, false. - public bool CanSelfRestart - { - get - { - // A restart script must be provided - return StartupOptions.ContainsOption("-restartpath"); - } - } - - /// - /// Restarts this instance. - /// - public void Restart(StartupOptions startupOptions) - { - MainClass.Restart(startupOptions); - } - - /// - /// Gets a value indicating whether this instance can self update. - /// - /// true if this instance can self update; otherwise, false. - public bool CanSelfUpdate - { - get - { - return false; - } - } - - public bool SupportsAutoRunAtStartup - { - get { return false; } - } - - public List GetAssembliesWithParts() - { - var list = new List(); - - list.Add(GetType().Assembly); - - return list; - } - - private IEnumerable GetLinuxAssemblies() - { - var list = new List(); - - //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) - { - - } - } -} diff --git a/MediaBrowser.Server.Mono/Native/MonoFileSystem.cs b/MediaBrowser.Server.Mono/Native/MonoFileSystem.cs index 9639566947..748b946046 100644 --- a/MediaBrowser.Server.Mono/Native/MonoFileSystem.cs +++ b/MediaBrowser.Server.Mono/Native/MonoFileSystem.cs @@ -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) { } diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs index 9a8ac7763d..48390f0784 100644 --- a/MediaBrowser.Server.Mono/Program.cs +++ b/MediaBrowser.Server.Mono/Program.cs @@ -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, diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index fa8cccf342..ab0a36affb 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -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 /// The options. 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 /// The instance containing the event data. 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(); } diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index f6aef57443..6984ff2bed 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -138,7 +138,6 @@ - @@ -156,6 +155,7 @@ SplashForm.cs + diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/WindowsAppHost.cs similarity index 62% rename from MediaBrowser.ServerApplication/Native/WindowsApp.cs rename to MediaBrowser.ServerApplication/WindowsAppHost.cs index babe952d6d..8fd7184321 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/WindowsAppHost.cs @@ -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 certificateGenerator, Func defaultUsernameFactory) + : base(applicationPaths, logManager, options, fileSystem, powerManagement, releaseAssetFilename, environmentInfo, imageEncoder, systemEvents, memoryStreamFactory, networkManager, certificateGenerator, defaultUsernameFactory) { - _fileSystem = fileSystem; - _logger = logger; } - public List GetAssembliesWithParts() + public override bool IsRunningAsService { - var list = new List(); - - if (!System.Environment.Is64BitProcess) - { - //list.Add(typeof(PismoIsoManager).Assembly); - } - - list.Add(GetType().Assembly); - - return list; + get { return MainStartup.IsRunningAsService; } } - 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 GetAssembliesWithPartsInternal() + { + var list = new List(); + + 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); - } - - /// - /// Processes the exited. - /// - /// The sender. - /// The instance containing the event data. 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; } } } + } -} \ No newline at end of file +} diff --git a/src/Emby.Server/ApplicationPathHelper.cs b/src/Emby.Server/ApplicationPathHelper.cs new file mode 100644 index 0000000000..4da87b6a06 --- /dev/null +++ b/src/Emby.Server/ApplicationPathHelper.cs @@ -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; + } + } +} diff --git a/src/Emby.Server/CoreAppHost.cs b/src/Emby.Server/CoreAppHost.cs new file mode 100644 index 0000000000..1a15265130 --- /dev/null +++ b/src/Emby.Server/CoreAppHost.cs @@ -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 certificateGenerator, Func 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 GetAssembliesWithPartsInternal() + { + var list = new List(); + + 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; + } + } + } +} diff --git a/src/Emby.Server/CoreSystemEvents.cs b/src/Emby.Server/CoreSystemEvents.cs new file mode 100644 index 0000000000..d83071fa81 --- /dev/null +++ b/src/Emby.Server/CoreSystemEvents.cs @@ -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; + } +} diff --git a/src/Emby.Server/Data/DbConnector.cs b/src/Emby.Server/Data/DbConnector.cs new file mode 100644 index 0000000000..bd70cff6cf --- /dev/null +++ b/src/Emby.Server/Data/DbConnector.cs @@ -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 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; + } + } +} \ No newline at end of file diff --git a/src/Emby.Server/IO/MemoryStreamFactory.cs b/src/Emby.Server/IO/MemoryStreamFactory.cs new file mode 100644 index 0000000000..37ac2959ed --- /dev/null +++ b/src/Emby.Server/IO/MemoryStreamFactory.cs @@ -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 arrayBuffer; + stream.TryGetBuffer(out arrayBuffer); + + buffer = arrayBuffer.Array; + return true; + } + } +} diff --git a/src/Emby.Server/PowerManagement.cs b/src/Emby.Server/PowerManagement.cs new file mode 100644 index 0000000000..85e3b72a69 --- /dev/null +++ b/src/Emby.Server/PowerManagement.cs @@ -0,0 +1,15 @@ +using MediaBrowser.Model.System; + +namespace Emby.Server +{ + public class PowerManagement : IPowerManagement + { + public void PreventSystemStandby() + { + } + + public void AllowSystemStandby() + { + } + } +} diff --git a/src/Emby.Server/Program.cs b/src/Emby.Server/Program.cs index d364e72842..64fc423a16 100644 --- a/src/Emby.Server/Program.cs +++ b/src/Emby.Server/Program.cs @@ -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 /// The options. 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(); @@ -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); } /// @@ -304,11 +275,6 @@ namespace Emby.Server /// private static void StartService(ILogManager logManager) { - var service = new BackgroundService(logManager.GetLogger("Service")); - - service.Disposed += service_Disposed; - - ServiceBase.Run(service); } /// @@ -329,19 +295,6 @@ namespace Emby.Server DisposeAppHost(); } - /// - /// Handles the SessionEnding event of the SystemEvents control. - /// - /// The source of the event. - /// The instance containing the event data. - static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e) - { - if (e.Reason == SessionEndReasons.SystemShutdown || !_isRunningAsService) - { - Shutdown(); - } - } - /// /// Handles the UnhandledException event of the CurrentDomain control. /// @@ -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() - - }).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"; - } - /// /// Sets the error mode. /// diff --git a/src/Emby.Server/project.json b/src/Emby.Server/project.json index 2693435a45..c64db844f9 100644 --- a/src/Emby.Server/project.json +++ b/src/Emby.Server/project.json @@ -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": {