update .net core startup

This commit is contained in:
Luke Pulverenti 2016-11-12 23:33:51 -05:00
parent 3e06bda46b
commit 95341c5c96
20 changed files with 602 additions and 632 deletions

View File

@ -18,12 +18,13 @@ namespace Emby.Common.Implementations.IO
private readonly bool _supportsAsyncFileStreams; private readonly bool _supportsAsyncFileStreams;
private char[] _invalidFileNameChars; private char[] _invalidFileNameChars;
private readonly List<IShortcutHandler> _shortcutHandlers = new List<IShortcutHandler>(); 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; Logger = logger;
_supportsAsyncFileStreams = supportsAsyncFileStreams; _supportsAsyncFileStreams = supportsAsyncFileStreams;
EnableFileSystemRequestConcat = enableFileSystemRequestConcat;
SetInvalidFileNameChars(enableManagedInvalidFileNameChars); SetInvalidFileNameChars(enableManagedInvalidFileNameChars);
} }

View File

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

View File

@ -142,7 +142,7 @@ namespace Emby.Server.Core
/// <summary> /// <summary>
/// Class CompositionRoot /// Class CompositionRoot
/// </summary> /// </summary>
public class ApplicationHost : BaseApplicationHost<ServerApplicationPaths>, IServerApplicationHost, IDependencyContainer public abstract class ApplicationHost : BaseApplicationHost<ServerApplicationPaths>, IServerApplicationHost, IDependencyContainer
{ {
/// <summary> /// <summary>
/// Gets the server configuration manager. /// Gets the server configuration manager.
@ -257,11 +257,9 @@ namespace Emby.Server.Core
protected IAuthService AuthService { get; private set; } protected IAuthService AuthService { get; private set; }
private readonly StartupOptions _startupOptions; protected readonly StartupOptions StartupOptions;
private readonly string _releaseAssetFilename; private readonly string _releaseAssetFilename;
internal INativeApp NativeApp { get; set; }
internal IPowerManagement PowerManagement { get; private set; } internal IPowerManagement PowerManagement { get; private set; }
internal IImageEncoder ImageEncoder { get; private set; } internal IImageEncoder ImageEncoder { get; private set; }
@ -275,7 +273,6 @@ namespace Emby.Server.Core
ILogManager logManager, ILogManager logManager,
StartupOptions options, StartupOptions options,
IFileSystem fileSystem, IFileSystem fileSystem,
INativeApp nativeApp,
IPowerManagement powerManagement, IPowerManagement powerManagement,
string releaseAssetFilename, string releaseAssetFilename,
IEnvironmentInfo environmentInfo, IEnvironmentInfo environmentInfo,
@ -293,11 +290,10 @@ namespace Emby.Server.Core
memoryStreamFactory, memoryStreamFactory,
networkManager) networkManager)
{ {
_startupOptions = options; StartupOptions = options;
_certificateGenerator = certificateGenerator; _certificateGenerator = certificateGenerator;
_releaseAssetFilename = releaseAssetFilename; _releaseAssetFilename = releaseAssetFilename;
_defaultUserNameFactory = defaultUsernameFactory; _defaultUserNameFactory = defaultUsernameFactory;
NativeApp = nativeApp;
PowerManagement = powerManagement; PowerManagement = powerManagement;
ImageEncoder = imageEncoder; ImageEncoder = imageEncoder;
@ -314,19 +310,11 @@ namespace Emby.Server.Core
{ {
get get
{ {
return _version ?? (_version = GetAssembly(NativeApp.GetType()).GetName().Version); return _version ?? (_version = GetAssembly(GetType()).GetName().Version);
} }
} }
public override bool IsRunningAsService public abstract bool SupportsRunningAsService { get; }
{
get { return NativeApp.IsRunningAsService; }
}
public bool SupportsRunningAsService
{
get { return NativeApp.SupportsRunningAsService; }
}
/// <summary> /// <summary>
/// Gets the name. /// Gets the name.
@ -345,19 +333,7 @@ namespace Emby.Server.Core
return type.GetTypeInfo().Assembly; return type.GetTypeInfo().Assembly;
} }
/// <summary> public abstract bool SupportsAutoRunAtStartup { get; }
/// 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; }
}
private void SetBaseExceptionMessage() private void SetBaseExceptionMessage()
{ {
@ -580,11 +556,11 @@ namespace Emby.Server.Core
UserRepository = await GetUserRepository().ConfigureAwait(false); 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; DisplayPreferencesRepository = displayPreferencesRepo;
RegisterSingleInstance(DisplayPreferencesRepository); RegisterSingleInstance(DisplayPreferencesRepository);
var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager, NativeApp.GetDbConnector(), MemoryStreamFactory); var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager, GetDbConnector(), MemoryStreamFactory);
ItemRepository = itemRepo; ItemRepository = itemRepo;
RegisterSingleInstance(ItemRepository); RegisterSingleInstance(ItemRepository);
@ -707,7 +683,7 @@ namespace Emby.Server.Core
EncodingManager = new EncodingManager(FileSystemManager, Logger, MediaEncoder, ChapterManager, LibraryManager); EncodingManager = new EncodingManager(FileSystemManager, Logger, MediaEncoder, ChapterManager, LibraryManager);
RegisterSingleInstance(EncodingManager); RegisterSingleInstance(EncodingManager);
var sharingRepo = new SharingRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector()); var sharingRepo = new SharingRepository(LogManager, ApplicationPaths, GetDbConnector());
await sharingRepo.Initialize().ConfigureAwait(false); await sharingRepo.Initialize().ConfigureAwait(false);
RegisterSingleInstance<ISharingManager>(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this)); RegisterSingleInstance<ISharingManager>(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this));
@ -727,7 +703,7 @@ namespace Emby.Server.Core
await displayPreferencesRepo.Initialize().ConfigureAwait(false); await displayPreferencesRepo.Initialize().ConfigureAwait(false);
var userDataRepo = new SqliteUserDataRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector()); var userDataRepo = new SqliteUserDataRepository(LogManager, ApplicationPaths, GetDbConnector());
((UserDataManager)UserDataManager).Repository = userDataRepo; ((UserDataManager)UserDataManager).Repository = userDataRepo;
await itemRepo.Initialize(userDataRepo).ConfigureAwait(false); await itemRepo.Initialize(userDataRepo).ConfigureAwait(false);
@ -770,14 +746,16 @@ namespace Emby.Server.Core
{ {
var maxConcurrentImageProcesses = Math.Max(Environment.ProcessorCount, 4); 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); return new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, ImageEncoder, maxConcurrentImageProcesses, () => LibraryManager, TimerFactory);
} }
protected abstract FFMpegInstallInfo GetFfmpegInstallInfo();
/// <summary> /// <summary>
/// Registers the media encoder. /// Registers the media encoder.
/// </summary> /// </summary>
@ -787,8 +765,8 @@ namespace Emby.Server.Core
string encoderPath = null; string encoderPath = null;
string probePath = null; string probePath = null;
var info = await new FFMpegLoader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, NativeApp.GetFfmpegInstallInfo()) var info = await new FFMpegLoader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, GetFfmpegInstallInfo())
.GetFFMpegInfo(_startupOptions, progress).ConfigureAwait(false); .GetFFMpegInfo(StartupOptions, progress).ConfigureAwait(false);
encoderPath = info.EncoderPath; encoderPath = info.EncoderPath;
probePath = info.ProbePath; probePath = info.ProbePath;
@ -825,7 +803,7 @@ namespace Emby.Server.Core
/// <returns>Task{IUserRepository}.</returns> /// <returns>Task{IUserRepository}.</returns>
private async Task<IUserRepository> GetUserRepository() 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); await repo.Initialize().ConfigureAwait(false);
@ -838,7 +816,7 @@ namespace Emby.Server.Core
/// <returns>Task{IUserRepository}.</returns> /// <returns>Task{IUserRepository}.</returns>
private async Task<IFileOrganizationRepository> GetFileOrganizationRepository() 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); await repo.Initialize().ConfigureAwait(false);
@ -847,7 +825,7 @@ namespace Emby.Server.Core
private async Task<IAuthenticationRepository> GetAuthenticationRepository() 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); await repo.Initialize().ConfigureAwait(false);
@ -856,7 +834,7 @@ namespace Emby.Server.Core
private async Task<IActivityRepository> GetActivityLogRepository() 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); await repo.Initialize().ConfigureAwait(false);
@ -865,7 +843,7 @@ namespace Emby.Server.Core
private async Task<ISyncRepository> GetSyncRepository() 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); await repo.Initialize().ConfigureAwait(false);
@ -877,7 +855,7 @@ namespace Emby.Server.Core
/// </summary> /// </summary>
private async Task ConfigureNotificationsRepository() private async Task ConfigureNotificationsRepository()
{ {
var repo = new SqliteNotificationsRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector()); var repo = new SqliteNotificationsRepository(LogManager, ApplicationPaths, GetDbConnector());
await repo.Initialize().ConfigureAwait(false); await repo.Initialize().ConfigureAwait(false);
@ -1123,24 +1101,12 @@ namespace Emby.Server.Core
Logger.ErrorException("Error sending server restart notification", ex); Logger.ErrorException("Error sending server restart notification", ex);
} }
Logger.Info("Calling NativeApp.Restart"); Logger.Info("Calling RestartInternal");
NativeApp.Restart(_startupOptions); RestartInternal();
} }
/// <summary> protected abstract void RestartInternal();
/// 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
}
}
/// <summary> /// <summary>
/// Gets the composable part assemblies. /// Gets the composable part assemblies.
@ -1196,14 +1162,16 @@ namespace Emby.Server.Core
// Xbmc // Xbmc
list.Add(GetAssembly(typeof(ArtistNfoProvider))); list.Add(GetAssembly(typeof(ArtistNfoProvider)));
list.AddRange(NativeApp.GetAssembliesWithParts()); list.AddRange(GetAssembliesWithPartsInternal());
// Include composable parts in the running assembly // Include composable parts in the running assembly
list.Add(GetAssembly(GetType())); list.Add(GetAssembly(typeof(ApplicationHost)));
return list; return list;
} }
protected abstract List<Assembly> GetAssembliesWithPartsInternal();
/// <summary> /// <summary>
/// Gets the plugin assemblies. /// Gets the plugin assemblies.
/// </summary> /// </summary>
@ -1280,7 +1248,7 @@ namespace Emby.Server.Core
EncoderLocationType = MediaEncoder.EncoderLocationType, EncoderLocationType = MediaEncoder.EncoderLocationType,
SystemArchitecture = EnvironmentInfo.SystemArchitecture, SystemArchitecture = EnvironmentInfo.SystemArchitecture,
SystemUpdateLevel = ConfigurationManager.CommonConfiguration.SystemUpdateLevel, 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); Logger.ErrorException("Error sending server shutdown notification", ex);
} }
NativeApp.Shutdown(); ShutdownInternal();
} }
protected abstract void ShutdownInternal();
/// <summary> /// <summary>
/// Registers the server with administrator access. /// Registers the server with administrator access.
/// </summary> /// </summary>
@ -1468,7 +1438,7 @@ namespace Emby.Server.Core
try try
{ {
NativeApp.AuthorizeServer( AuthorizeServer(
UdpServerEntryPoint.PortNumber, UdpServerEntryPoint.PortNumber,
ServerConfigurationManager.Configuration.HttpServerPortNumber, ServerConfigurationManager.Configuration.HttpServerPortNumber,
ServerConfigurationManager.Configuration.HttpsPortNumber, 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; public event EventHandler HasUpdateAvailableChanged;
private bool _hasUpdateAvailable; private bool _hasUpdateAvailable;
@ -1551,10 +1524,12 @@ namespace Emby.Server.Core
{ {
if (SupportsAutoRunAtStartup) if (SupportsAutoRunAtStartup)
{ {
NativeApp.ConfigureAutoRun(autorun); ConfigureAutoRunInternal(autorun);
} }
} }
protected abstract void ConfigureAutoRunInternal(bool autorun);
/// <summary> /// <summary>
/// This returns localhost in the case of no external dns, and the hostname if the /// This returns localhost in the case of no external dns, and the hostname if the
/// dns is prefixed with a valid Uri prefix. /// dns is prefixed with a valid Uri prefix.
@ -1578,16 +1553,15 @@ namespace Emby.Server.Core
} }
} }
public void LaunchUrl(string url) public abstract void LaunchUrl(string url);
{
NativeApp.LaunchUrl(url);
}
public void EnableLoopback(string appName) public void EnableLoopback(string appName)
{ {
NativeApp.EnableLoopback(appName); EnableLoopbackInternal(appName);
} }
protected abstract void EnableLoopbackInternal(string appName);
private void RegisterModules() private void RegisterModules()
{ {
var moduleTypes = GetExportTypes<IDependencyModule>(); var moduleTypes = GetExportTypes<IDependencyModule>();

View File

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

View File

@ -106,7 +106,7 @@
<Compile Include="..\SharedVersion.cs"> <Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link> <Link>Properties\SharedVersion.cs</Link>
</Compile> </Compile>
<Compile Include="Native\MonoApp.cs" /> <Compile Include="MonoAppHost.cs" />
<Compile Include="Native\DbConnector.cs" /> <Compile Include="Native\DbConnector.cs" />
<Compile Include="Native\MonoFileSystem.cs" /> <Compile Include="Native\MonoFileSystem.cs" />
<Compile Include="Native\PowerManagement.cs" /> <Compile Include="Native\PowerManagement.cs" />

View File

@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Emby.Server.Core;
using Emby.Server.Core.Data;
using Emby.Server.Core.FFMpeg;
using MediaBrowser.IsoMounter;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.System;
using MediaBrowser.Server.Mono.Native;
namespace MediaBrowser.Server.Mono
{
public class MonoAppHost : ApplicationHost
{
public MonoAppHost(ServerApplicationPaths applicationPaths, ILogManager logManager, StartupOptions options, IFileSystem fileSystem, IPowerManagement powerManagement, string releaseAssetFilename, IEnvironmentInfo environmentInfo, MediaBrowser.Controller.Drawing.IImageEncoder imageEncoder, ISystemEvents systemEvents, IMemoryStreamFactory memoryStreamFactory, MediaBrowser.Common.Net.INetworkManager networkManager, Action<string, string> certificateGenerator, Func<string> defaultUsernameFactory) : base(applicationPaths, logManager, options, fileSystem, powerManagement, releaseAssetFilename, environmentInfo, imageEncoder, systemEvents, memoryStreamFactory, networkManager, certificateGenerator, defaultUsernameFactory)
{
}
public override bool CanSelfRestart
{
get
{
// A restart script must be provided
return StartupOptions.ContainsOption("-restartpath");
}
}
public override bool CanSelfUpdate
{
get
{
return false;
}
}
protected override FFMpegInstallInfo GetFfmpegInstallInfo()
{
var info = new FFMpegInstallInfo();
// Windows builds: http://ffmpeg.zeranoe.com/builds/
// Linux builds: http://johnvansickle.com/ffmpeg/
// OS X builds: http://ffmpegmac.net/
// OS X x64: http://www.evermeet.cx/ffmpeg/
var environment = (MonoEnvironmentInfo) EnvironmentInfo;
if (environment.IsBsd)
{
}
else if (environment.OperatingSystem == Model.System.OperatingSystem.Linux)
{
info.ArchiveType = "7z";
info.Version = "20160215";
}
// No version available - user requirement
info.DownloadUrls = new string[] { };
return info;
}
protected override void RestartInternal()
{
MainClass.Restart(StartupOptions);
}
protected override List<Assembly> GetAssembliesWithPartsInternal()
{
var list = new List<Assembly>();
list.Add(GetType().Assembly);
list.AddRange(GetLinuxAssemblies());
return list;
}
private IEnumerable<Assembly> GetLinuxAssemblies()
{
var list = new List<Assembly>();
list.Add(typeof(LinuxIsoManager).Assembly);
return list;
}
protected override void ShutdownInternal()
{
MainClass.Shutdown();
}
protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory)
{
throw new NotImplementedException();
}
protected override IDbConnector GetDbConnector()
{
return new DbConnector(Logger);
}
protected override void ConfigureAutoRunInternal(bool autorun)
{
throw new NotImplementedException();
}
public override void LaunchUrl(string url)
{
throw new NotImplementedException();
}
protected override void EnableLoopbackInternal(string appName)
{
}
public override bool SupportsRunningAsService
{
get
{
return false;
}
}
public override bool SupportsAutoRunAtStartup
{
get { return false; }
}
public override bool IsRunningAsService
{
get
{
return false;
}
}
}
}

View File

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

View File

@ -6,7 +6,7 @@ namespace MediaBrowser.Server.Mono.Native
{ {
public class MonoFileSystem : ManagedFileSystem 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)
{ {
} }

View File

@ -91,15 +91,12 @@ namespace MediaBrowser.Server.Mono
var environmentInfo = GetEnvironmentInfo(); var environmentInfo = GetEnvironmentInfo();
var nativeApp = new MonoApp(options, logManager.GetLogger("App"), environmentInfo);
var imageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => _appHost.HttpClient, appPaths); var imageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => _appHost.HttpClient, appPaths);
_appHost = new ApplicationHost(appPaths, _appHost = new MonoAppHost(appPaths,
logManager, logManager,
options, options,
fileSystem, fileSystem,
nativeApp,
new PowerManagement(), new PowerManagement(),
"emby.mono.zip", "emby.mono.zip",
environmentInfo, environmentInfo,

View File

@ -37,7 +37,7 @@ namespace MediaBrowser.ServerApplication
private static ILogger _logger; private static ILogger _logger;
private static bool _isRunningAsService = false; public static bool IsRunningAsService = false;
private static bool _canRestartService = false; private static bool _canRestartService = false;
private static bool _appHostDisposed; private static bool _appHostDisposed;
@ -72,9 +72,9 @@ namespace MediaBrowser.ServerApplication
public static void Main() public static void Main()
{ {
var options = new StartupOptions(); var options = new StartupOptions();
_isRunningAsService = options.ContainsOption("-service"); IsRunningAsService = options.ContainsOption("-service");
if (_isRunningAsService) if (IsRunningAsService)
{ {
//_canRestartService = CanRestartWindowsService(); //_canRestartService = CanRestartWindowsService();
} }
@ -88,7 +88,7 @@ namespace MediaBrowser.ServerApplication
var success = SetDllDirectory(architecturePath); var success = SetDllDirectory(architecturePath);
var appPaths = CreateApplicationPaths(applicationPath, _isRunningAsService); var appPaths = CreateApplicationPaths(applicationPath, IsRunningAsService);
var logManager = new NlogManager(appPaths.LogDirectoryPath, "server"); var logManager = new NlogManager(appPaths.LogDirectoryPath, "server");
logManager.ReloadLogger(LogSeverity.Debug); logManager.ReloadLogger(LogSeverity.Debug);
@ -148,7 +148,7 @@ namespace MediaBrowser.ServerApplication
try try
{ {
RunApplication(appPaths, logManager, _isRunningAsService, options); RunApplication(appPaths, logManager, IsRunningAsService, options);
} }
finally finally
{ {
@ -204,7 +204,7 @@ namespace MediaBrowser.ServerApplication
} }
} }
if (!_isRunningAsService) if (!IsRunningAsService)
{ {
return IsAlreadyRunningAsService(applicationPath); return IsAlreadyRunningAsService(applicationPath);
} }
@ -272,7 +272,7 @@ namespace MediaBrowser.ServerApplication
{ {
get get
{ {
if (_isRunningAsService) if (IsRunningAsService)
{ {
return _canRestartService; return _canRestartService;
} }
@ -295,7 +295,7 @@ namespace MediaBrowser.ServerApplication
return false; return false;
#endif #endif
if (_isRunningAsService) if (IsRunningAsService)
{ {
return _canRestartService; return _canRestartService;
} }
@ -317,22 +317,16 @@ namespace MediaBrowser.ServerApplication
/// <param name="options">The options.</param> /// <param name="options">The options.</param>
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, bool runService, StartupOptions 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 LnkShortcutHandler());
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
var nativeApp = new WindowsApp(fileSystem, _logger)
{
IsRunningAsService = runService
};
var imageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => _appHost.HttpClient, appPaths); var imageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => _appHost.HttpClient, appPaths);
_appHost = new ApplicationHost(appPaths, _appHost = new WindowsAppHost(appPaths,
logManager, logManager,
options, options,
fileSystem, fileSystem,
nativeApp,
new PowerManagement(), new PowerManagement(),
"emby.windows.zip", "emby.windows.zip",
new EnvironmentInfo(), new EnvironmentInfo(),
@ -440,7 +434,7 @@ namespace MediaBrowser.ServerApplication
public static void Invoke(Action action) public static void Invoke(Action action)
{ {
if (_isRunningAsService) if (IsRunningAsService)
{ {
action(); action();
} }
@ -578,7 +572,7 @@ namespace MediaBrowser.ServerApplication
/// <param name="e">The <see cref="SessionEndingEventArgs"/> instance containing the event data.</param> /// <param name="e">The <see cref="SessionEndingEventArgs"/> instance containing the event data.</param>
static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e) static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
{ {
if (e.Reason == SessionEndReasons.SystemShutdown || !_isRunningAsService) if (e.Reason == SessionEndReasons.SystemShutdown || !IsRunningAsService)
{ {
Shutdown(); Shutdown();
} }
@ -595,7 +589,7 @@ namespace MediaBrowser.ServerApplication
new UnhandledExceptionWriter(_appHost.ServerConfigurationManager.ApplicationPaths, _logger, _appHost.LogManager).Log(exception); new UnhandledExceptionWriter(_appHost.ServerConfigurationManager.ApplicationPaths, _logger, _appHost.LogManager).Log(exception);
if (!_isRunningAsService) if (!IsRunningAsService)
{ {
MessageBox.Show("Unhandled exception: " + exception.Message); MessageBox.Show("Unhandled exception: " + exception.Message);
} }
@ -623,7 +617,7 @@ namespace MediaBrowser.ServerApplication
// Update is there - execute update // Update is there - execute update
try try
{ {
var serviceName = _isRunningAsService ? BackgroundService.GetExistingServiceName() : string.Empty; var serviceName = IsRunningAsService ? BackgroundService.GetExistingServiceName() : string.Empty;
new ApplicationUpdater().UpdateApplication(appPaths, updateArchive, logger, serviceName); new ApplicationUpdater().UpdateApplication(appPaths, updateArchive, logger, serviceName);
// And just let the app exit so it can update // And just let the app exit so it can update
@ -642,7 +636,7 @@ namespace MediaBrowser.ServerApplication
public static void Shutdown() public static void Shutdown()
{ {
if (_isRunningAsService) if (IsRunningAsService)
{ {
ShutdownWindowsService(); ShutdownWindowsService();
} }
@ -658,7 +652,7 @@ namespace MediaBrowser.ServerApplication
{ {
DisposeAppHost(); DisposeAppHost();
if (_isRunningAsService) if (IsRunningAsService)
{ {
RestartWindowsService(); RestartWindowsService();
} }

View File

@ -138,7 +138,6 @@
<Compile Include="Native\PowerManagement.cs" /> <Compile Include="Native\PowerManagement.cs" />
<Compile Include="Native\Standby.cs" /> <Compile Include="Native\Standby.cs" />
<Compile Include="Native\ServerAuthorization.cs" /> <Compile Include="Native\ServerAuthorization.cs" />
<Compile Include="Native\WindowsApp.cs" />
<Compile Include="Networking\NativeMethods.cs" /> <Compile Include="Networking\NativeMethods.cs" />
<Compile Include="Networking\NetworkManager.cs" /> <Compile Include="Networking\NetworkManager.cs" />
<Compile Include="Networking\NetworkShares.cs" /> <Compile Include="Networking\NetworkShares.cs" />
@ -156,6 +155,7 @@
<DependentUpon>SplashForm.cs</DependentUpon> <DependentUpon>SplashForm.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Updates\ApplicationUpdater.cs" /> <Compile Include="Updates\ApplicationUpdater.cs" />
<Compile Include="WindowsAppHost.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />

View File

@ -1,131 +1,31 @@
using System; 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.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Windows.Forms;
using Emby.Server.Core; using Emby.Server.Core;
using Emby.Server.Core.Data; using Emby.Server.Core.Data;
using Emby.Server.Core.FFMpeg; using Emby.Server.Core.FFMpeg;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.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; 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)
private readonly ILogger _logger; : base(applicationPaths, logManager, options, fileSystem, powerManagement, releaseAssetFilename, environmentInfo, imageEncoder, systemEvents, memoryStreamFactory, networkManager, certificateGenerator, defaultUsernameFactory)
public WindowsApp(IFileSystem fileSystem, ILogger logger)
{ {
_fileSystem = fileSystem;
_logger = logger;
} }
public List<Assembly> GetAssembliesWithParts() public override bool IsRunningAsService
{ {
var list = new List<Assembly>(); get { return MainStartup.IsRunningAsService; }
if (!System.Environment.Is64BitProcess)
{
//list.Add(typeof(PismoIsoManager).Assembly);
}
list.Add(GetType().Assembly);
return list;
} }
public void AuthorizeServer(int udpPort, int httpServerPort, int httpsPort, string applicationPath, string tempDirectory) protected override FFMpegInstallInfo GetFfmpegInstallInfo()
{
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()
{ {
var info = new FFMpegInstallInfo(); var info = new FFMpegInstallInfo();
@ -136,7 +36,61 @@ namespace MediaBrowser.ServerApplication.Native
return info; return info;
} }
public void LaunchUrl(string url) protected override void RestartInternal()
{
MainStartup.Restart();
}
protected override List<Assembly> GetAssembliesWithPartsInternal()
{
var list = new List<Assembly>();
if (!Environment.Is64BitProcess)
{
//list.Add(typeof(PismoIsoManager).Assembly);
}
list.Add(GetType().Assembly);
return list;
}
protected override void ShutdownInternal()
{
MainStartup.Shutdown();
}
protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory)
{
ServerAuthorization.AuthorizeServer(udpPort, httpServerPort, httpsServerPort, applicationPath, tempDirectory);
}
protected override IDbConnector GetDbConnector()
{
return new DbConnector(Logger);
}
protected override void ConfigureAutoRunInternal(bool autorun)
{
var shortcutPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.StartMenu), "Emby", "Emby Server.lnk");
var startupPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Startup);
if (autorun)
{
//Copy our shortut into the startup folder for this user
var targetPath = Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk");
FileSystemManager.CreateDirectory(Path.GetDirectoryName(targetPath));
File.Copy(shortcutPath, targetPath, true);
}
else
{
//Remove our shortcut from the startup folder for this user
FileSystemManager.DeleteFile(Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk"));
}
}
public override void LaunchUrl(string url)
{ {
var process = new Process var process = new Process
{ {
@ -156,32 +110,54 @@ namespace MediaBrowser.ServerApplication.Native
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.ErrorException("Error launching url: {0}", ex, url); Logger.ErrorException("Error launching url: {0}", ex, url);
throw; 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) private static void ProcessExited(object sender, EventArgs e)
{ {
((Process)sender).Dispose(); ((Process)sender).Dispose();
} }
public void EnableLoopback(string appName) protected override void EnableLoopbackInternal(string appName)
{ {
LoopUtil.Run(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) public bool PortsRequireAuthorization(string applicationPath)
{ {
var appNameSrch = Path.GetFileName(applicationPath); var appNameSrch = Path.GetFileName(applicationPath);
@ -209,7 +185,7 @@ namespace MediaBrowser.ServerApplication.Native
if (data.IndexOf("Block", StringComparison.OrdinalIgnoreCase) != -1) 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'); //var parts = data.Split('\n');
@ -220,7 +196,7 @@ namespace MediaBrowser.ServerApplication.Native
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.ErrorException("Error querying windows firewall", ex); Logger.ErrorException("Error querying windows firewall", ex);
// Hate having to do this // Hate having to do this
try try
@ -229,12 +205,13 @@ namespace MediaBrowser.ServerApplication.Native
} }
catch (Exception ex1) catch (Exception ex1)
{ {
_logger.ErrorException("Error killing process", ex1); Logger.ErrorException("Error killing process", ex1);
} }
throw; throw;
} }
} }
} }
} }
} }

View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace Emby.Server
{
public class ApplicationPathHelper
{
public static string GetProgramDataPath(string applicationPath)
{
var useDebugPath = false;
#if DEBUG
useDebugPath = true;
#endif
var programDataPath = useDebugPath ?
"programdata" :
"programdata";
programDataPath = programDataPath
.Replace('/', Path.DirectorySeparatorChar)
.Replace('\\', Path.DirectorySeparatorChar);
// If it's a relative path, e.g. "..\"
if (!Path.IsPathRooted(programDataPath))
{
var path = Path.GetDirectoryName(applicationPath);
if (string.IsNullOrEmpty(path))
{
throw new Exception("Unable to determine running assembly location");
}
programDataPath = Path.Combine(path, programDataPath);
programDataPath = Path.GetFullPath(programDataPath);
}
Directory.CreateDirectory(programDataPath);
return programDataPath;
}
}
}

View File

@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Emby.Server.Core;
using Emby.Server.Core.Data;
using Emby.Server.Core.FFMpeg;
using Emby.Server.Data;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.System;
namespace Emby.Server
{
public class CoreAppHost : ApplicationHost
{
public CoreAppHost(ServerApplicationPaths applicationPaths, ILogManager logManager, StartupOptions options, IFileSystem fileSystem, IPowerManagement powerManagement, string releaseAssetFilename, IEnvironmentInfo environmentInfo, MediaBrowser.Controller.Drawing.IImageEncoder imageEncoder, ISystemEvents systemEvents, IMemoryStreamFactory memoryStreamFactory, MediaBrowser.Common.Net.INetworkManager networkManager, Action<string, string> certificateGenerator, Func<string> defaultUsernameFactory)
: base(applicationPaths, logManager, options, fileSystem, powerManagement, releaseAssetFilename, environmentInfo, imageEncoder, systemEvents, memoryStreamFactory, networkManager, certificateGenerator, defaultUsernameFactory)
{
}
public override bool IsRunningAsService
{
get { return false; }
}
protected override void RestartInternal()
{
Program.Restart();
}
protected override void ShutdownInternal()
{
Program.Shutdown();
}
protected override FFMpegInstallInfo GetFfmpegInstallInfo()
{
var info = new FFMpegInstallInfo();
return info;
}
protected override List<Assembly> GetAssembliesWithPartsInternal()
{
var list = new List<Assembly>();
list.Add(GetType().GetTypeInfo().Assembly);
return list;
}
protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory)
{
}
protected override IDbConnector GetDbConnector()
{
return new DbConnector(Logger);
}
protected override void ConfigureAutoRunInternal(bool autorun)
{
}
public override void LaunchUrl(string url)
{
}
protected override void EnableLoopbackInternal(string appName)
{
}
public override bool SupportsRunningAsService
{
get
{
return true;
}
}
public override bool CanSelfRestart
{
get
{
return Program.CanSelfRestart;
}
}
public override bool SupportsAutoRunAtStartup
{
get
{
return true;
}
}
public override bool CanSelfUpdate
{
get
{
return Program.CanSelfUpdate;
}
}
}
}

View File

@ -0,0 +1,11 @@
using System;
using MediaBrowser.Model.System;
namespace Emby.Server
{
public class CoreSystemEvents : ISystemEvents
{
public event EventHandler Resume;
public event EventHandler Suspend;
}
}

View File

@ -0,0 +1,52 @@
using System;
using System.Data;
using System.Threading.Tasks;
using MediaBrowser.Model.Logging;
using Emby.Server.Core.Data;
using Microsoft.Data.Sqlite;
namespace Emby.Server.Data
{
public class DbConnector : IDbConnector
{
private readonly ILogger _logger;
public DbConnector(ILogger logger)
{
_logger = logger;
}
public async Task<IDbConnection> Connect(string dbPath, bool isReadOnly, bool enablePooling = false, int? cacheSize = null)
{
if (string.IsNullOrEmpty(dbPath))
{
throw new ArgumentNullException("dbPath");
}
//SQLiteConnection.SetMemoryStatus(false);
var connectionstr = new SqliteConnectionStringBuilder
{
//PageSize = 4096,
//CacheSize = cacheSize ?? 2000,
//SyncMode = SynchronizationModes.Normal,
DataSource = dbPath,
//JournalMode = SQLiteJournalModeEnum.Wal,
// This is causing crashing under linux
//Pooling = enablePooling && Environment.OSVersion.Platform == PlatformID.Win32NT,
//ReadOnly = isReadOnly,
Cache = enablePooling ? SqliteCacheMode.Default : SqliteCacheMode.Private,
Mode = isReadOnly ? SqliteOpenMode.ReadOnly : SqliteOpenMode.ReadWriteCreate
};
var connectionString = connectionstr.ConnectionString;
var connection = new SqliteConnection(connectionString);
await connection.OpenAsync().ConfigureAwait(false);
return connection;
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.IO;
using MediaBrowser.Model.IO;
namespace Emby.Server.IO
{
public class MemoryStreamFactory : IMemoryStreamFactory
{
public MemoryStream CreateNew()
{
return new MemoryStream();
}
public MemoryStream CreateNew(int capacity)
{
return new MemoryStream(capacity);
}
public MemoryStream CreateNew(byte[] buffer)
{
return new MemoryStream(buffer);
}
public bool TryGetBuffer(MemoryStream stream, out byte[] buffer)
{
ArraySegment<byte> arrayBuffer;
stream.TryGetBuffer(out arrayBuffer);
buffer = arrayBuffer.Array;
return true;
}
}
}

View File

@ -0,0 +1,15 @@
using MediaBrowser.Model.System;
namespace Emby.Server
{
public class PowerManagement : IPowerManagement
{
public void PreventSystemStandby()
{
}
public void AllowSystemStandby()
{
}
}
}

View File

@ -1,33 +1,24 @@
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
using MediaBrowser.Server.Implementations; 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 Microsoft.Win32;
using System; using System;
using System.Configuration.Install;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Management;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms;
using Emby.Common.Implementations.EnvironmentInfo; using Emby.Common.Implementations.EnvironmentInfo;
using Emby.Common.Implementations.IO; using Emby.Common.Implementations.IO;
using Emby.Common.Implementations.Logging; using Emby.Common.Implementations.Logging;
using Emby.Common.Implementations.Networking; using Emby.Common.Implementations.Networking;
using Emby.Common.Implementations.Security; using Emby.Drawing;
using Emby.Server.Core; using Emby.Server.Core;
using Emby.Server.Core.Browser; using Emby.Server.Core.Browser;
using Emby.Server.Implementations.IO; using Emby.Server.Implementations.IO;
using ImageMagickSharp;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Server.Startup.Common.IO; using Emby.Server.IO;
namespace Emby.Server namespace Emby.Server
{ {
@ -60,11 +51,11 @@ namespace Emby.Server
var currentProcess = Process.GetCurrentProcess(); var currentProcess = Process.GetCurrentProcess();
var applicationPath = currentProcess.MainModule.FileName; 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); var appPaths = CreateApplicationPaths(applicationPath, _isRunningAsService);
@ -227,31 +218,25 @@ namespace Emby.Server
/// <param name="options">The options.</param> /// <param name="options">The options.</param>
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, bool runService, StartupOptions 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)); fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
var nativeApp = new WindowsApp(fileSystem, _logger) var imageEncoder = new NullImageEncoder();
{
IsRunningAsService = runService
};
var imageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => _appHost.HttpClient, appPaths); _appHost = new CoreAppHost(appPaths,
_appHost = new ApplicationHost(appPaths,
logManager, logManager,
options, options,
fileSystem, fileSystem,
nativeApp,
new PowerManagement(), new PowerManagement(),
"emby.windows.zip", "emby.windows.zip",
new EnvironmentInfo(), new EnvironmentInfo(),
imageEncoder, imageEncoder,
new Server.Startup.Common.SystemEvents(logManager.GetLogger("SystemEvents")), new CoreSystemEvents(),
new RecyclableMemoryStreamProvider(), new MemoryStreamFactory(),
new NetworkManager(logManager.GetLogger("NetworkManager")), new NetworkManager(logManager.GetLogger("NetworkManager")),
GenerateCertificate, GenerateCertificate,
() => Environment.UserDomainName); () => "EmbyUser");
var initProgress = new Progress<double>(); var initProgress = new Progress<double>();
@ -275,12 +260,6 @@ namespace Emby.Server
{ {
Task.WaitAll(task); 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 = ApplicationTaskCompletionSource.Task;
Task.WaitAll(task); Task.WaitAll(task);
} }
@ -288,15 +267,7 @@ namespace Emby.Server
private static void GenerateCertificate(string certPath, string certHost) private static void GenerateCertificate(string certPath, string certHost)
{ {
CertificateGenerator.CreateSelfSignCertificatePfx(certPath, certHost, _logger); //CertificateGenerator.CreateSelfSignCertificatePfx(certPath, certHost, _logger);
}
static void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
{
if (e.Reason == SessionSwitchReason.SessionLogon)
{
BrowserLauncher.OpenDashboard(_appHost);
}
} }
/// <summary> /// <summary>
@ -304,11 +275,6 @@ namespace Emby.Server
/// </summary> /// </summary>
private static void StartService(ILogManager logManager) private static void StartService(ILogManager logManager)
{ {
var service = new BackgroundService(logManager.GetLogger("Service"));
service.Disposed += service_Disposed;
ServiceBase.Run(service);
} }
/// <summary> /// <summary>
@ -329,19 +295,6 @@ namespace Emby.Server
DisposeAppHost(); 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> /// <summary>
/// Handles the UnhandledException event of the CurrentDomain control. /// Handles the UnhandledException event of the CurrentDomain control.
/// </summary> /// </summary>
@ -355,7 +308,7 @@ namespace Emby.Server
if (!_isRunningAsService) if (!_isRunningAsService)
{ {
MessageBox.Show("Unhandled exception: " + exception.Message); ShowMessageBox("Unhandled exception: " + exception.Message);
} }
if (!Debugger.IsAttached) if (!Debugger.IsAttached)
@ -381,8 +334,8 @@ namespace Emby.Server
// Update is there - execute update // Update is there - execute update
try try
{ {
var serviceName = _isRunningAsService ? BackgroundService.GetExistingServiceName() : string.Empty; //var serviceName = _isRunningAsService ? BackgroundService.GetExistingServiceName() : string.Empty;
new ApplicationUpdater().UpdateApplication(appPaths, updateArchive, logger, serviceName); //new ApplicationUpdater().UpdateApplication(appPaths, updateArchive, logger, serviceName);
// And just let the app exit so it can update // And just let the app exit so it can update
return true; return true;
@ -391,13 +344,18 @@ namespace Emby.Server
{ {
logger.ErrorException("Error starting updater.", e); 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; return false;
} }
private static void ShowMessageBox(string msg)
{
}
public static void Shutdown() public static void Shutdown()
{ {
if (_isRunningAsService) if (_isRunningAsService)
@ -469,90 +427,6 @@ namespace Emby.Server
return false; 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> /// <summary>
/// Sets the error mode. /// Sets the error mode.
/// </summary> /// </summary>

View File

@ -11,7 +11,11 @@
"type": "platform", "type": "platform",
"version": "1.0.1" "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": { "frameworks": {