Explorar o código

update .net core startup

Luke Pulverenti %!s(int64=8) %!d(string=hai) anos
pai
achega
95341c5c96

+ 3 - 2
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<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);
         }
 

+ 0 - 13
Emby.Common.Implementations/IO/WindowsFileSystem.cs

@@ -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;
-        }
-    }
-}

+ 44 - 70
Emby.Server.Core/ApplicationHost.cs

@@ -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>();

+ 0 - 78
Emby.Server.Core/INativeApp.cs

@@ -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&lt;Assembly&gt;.</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);
-    }
-}

+ 1 - 1
MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj

@@ -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 - 0
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<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;
+            }
+        }
+    }
+}

+ 0 - 164
MediaBrowser.Server.Mono/Native/MonoApp.cs

@@ -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)
-        {
-
-        }
-    }
-}

+ 1 - 1
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)
         {
         }
 

+ 1 - 4
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,

+ 16 - 22
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
         /// <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();
             }

+ 1 - 1
MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj

@@ -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" />

+ 75 - 98
MediaBrowser.ServerApplication/Native/WindowsApp.cs → MediaBrowser.ServerApplication/WindowsAppHost.cs

@@ -1,142 +1,96 @@
 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);
-            }
-
-            list.Add(GetType().Assembly);
-
-            return list;
+            get { return MainStartup.IsRunningAsService; }
         }
 
-        public void AuthorizeServer(int udpPort, int httpServerPort, int httpsPort, string applicationPath, string tempDirectory)
+        protected override FFMpegInstallInfo GetFfmpegInstallInfo()
         {
-            ServerAuthorization.AuthorizeServer(udpPort, httpServerPort, httpsPort, applicationPath, tempDirectory);
-        }
+            var info = new FFMpegInstallInfo();
 
-        public bool SupportsLibraryMonitor
-        {
-            get { return true; }
-        }
+            info.FFMpegFilename = "ffmpeg.exe";
+            info.FFProbeFilename = "ffprobe.exe";
+            info.Version = "0";
 
-        public bool SupportsRunningAsService
-        {
-            get
-            {
-                return true;
-            }
+            return info;
         }
 
-        public bool IsRunningAsService
+        protected override void RestartInternal()
         {
-            get;
-            set;
+            MainStartup.Restart();
         }
 
-        public bool CanSelfRestart
+        protected override List<Assembly> GetAssembliesWithPartsInternal()
         {
-            get
-            {
-                return MainStartup.CanSelfRestart;
-            }
-        }
+            var list = new List<Assembly>();
 
-        public bool SupportsAutoRunAtStartup
-        {
-            get
+            if (!Environment.Is64BitProcess)
             {
-                return true;
+                //list.Add(typeof(PismoIsoManager).Assembly);
             }
+
+            list.Add(GetType().Assembly);
+
+            return list;
         }
 
-        public bool CanSelfUpdate
+        protected override void ShutdownInternal()
         {
-            get
-            {
-                return MainStartup.CanSelfUpdate;
-            }
+            MainStartup.Shutdown();
         }
 
-        public void Shutdown()
+        protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory)
         {
-            MainStartup.Shutdown();
+            ServerAuthorization.AuthorizeServer(udpPort, httpServerPort, httpsServerPort, applicationPath, tempDirectory);
         }
 
-        public void Restart(StartupOptions startupOptions)
+        protected override IDbConnector GetDbConnector()
         {
-            MainStartup.Restart();
+            return new DbConnector(Logger);
         }
 
-        public void ConfigureAutoRun(bool autorun)
+        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");
-                _fileSystem.CreateDirectory(Path.GetDirectoryName(targetPath));
+                FileSystemManager.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"));
+                FileSystemManager.DeleteFile(Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk"));
             }
         }
 
-        public INetworkManager CreateNetworkManager(ILogger logger)
-        {
-            return new NetworkManager(logger);
-        }
-
-        public FFMpegInstallInfo GetFfmpegInstallInfo()
-        {
-            var info = new FFMpegInstallInfo();
-
-            info.FFMpegFilename = "ffmpeg.exe";
-            info.FFProbeFilename = "ffprobe.exe";
-            info.Version = "0";
-
-            return info;
-        }
-
-        public void LaunchUrl(string url)
+        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 - 0
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;
+        }
+    }
+}

+ 107 - 0
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<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 - 0
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;
+    }
+}

+ 52 - 0
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<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 - 0
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<byte> arrayBuffer;
+            stream.TryGetBuffer(out arrayBuffer);
+
+            buffer = arrayBuffer.Array;
+            return true;
+        }
+    }
+}

+ 15 - 0
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()
+        {
+        }
+    }
+}

+ 22 - 148
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
         /// <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());
-            fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
+            var fileSystem = new ManagedFileSystem(logManager.GetLogger("FileSystem"), true, true, true);
 
-            var nativeApp = new WindowsApp(fileSystem, _logger)
-            {
-                IsRunningAsService = runService
-            };
+            fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
 
-            var imageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => _appHost.HttpClient, appPaths);
+            var imageEncoder = new NullImageEncoder();
 
-            _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>

+ 5 - 1
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": {