2017-09-09 18:51:24 +00:00
using Emby.Common.Implementations.Serialization ;
2017-08-09 19:56:38 +00:00
using Emby.Dlna ;
using Emby.Dlna.ConnectionManager ;
using Emby.Dlna.ContentDirectory ;
using Emby.Dlna.Main ;
using Emby.Dlna.MediaReceiverRegistrar ;
using Emby.Dlna.Ssdp ;
using Emby.Drawing ;
using Emby.Photos ;
2017-09-09 18:51:24 +00:00
using Emby.Server.Core.Cryptography ;
2017-08-09 19:56:38 +00:00
using Emby.Server.Implementations.Activity ;
2017-09-09 18:51:24 +00:00
using Emby.Server.Implementations.Archiving ;
2017-08-09 19:56:38 +00:00
using Emby.Server.Implementations.Channels ;
using Emby.Server.Implementations.Collections ;
using Emby.Server.Implementations.Configuration ;
2017-09-09 18:51:24 +00:00
using Emby.Server.Implementations.Cryptography ;
2017-08-09 19:56:38 +00:00
using Emby.Server.Implementations.Data ;
using Emby.Server.Implementations.Devices ;
2017-09-09 18:51:24 +00:00
using Emby.Server.Implementations.Diagnostics ;
2017-08-09 19:56:38 +00:00
using Emby.Server.Implementations.Dto ;
using Emby.Server.Implementations.FFMpeg ;
using Emby.Server.Implementations.HttpServer ;
using Emby.Server.Implementations.HttpServer.Security ;
using Emby.Server.Implementations.IO ;
using Emby.Server.Implementations.Library ;
using Emby.Server.Implementations.LiveTv ;
using Emby.Server.Implementations.Localization ;
using Emby.Server.Implementations.MediaEncoder ;
2017-09-09 18:51:24 +00:00
using Emby.Server.Implementations.Net ;
2017-08-09 19:56:38 +00:00
using Emby.Server.Implementations.Notifications ;
using Emby.Server.Implementations.Playlists ;
2017-09-09 18:51:24 +00:00
using Emby.Server.Implementations.Reflection ;
using Emby.Server.Implementations.ScheduledTasks ;
2017-08-09 19:56:38 +00:00
using Emby.Server.Implementations.Security ;
2017-09-09 18:51:24 +00:00
using Emby.Server.Implementations.Serialization ;
2017-08-09 19:56:38 +00:00
using Emby.Server.Implementations.Session ;
using Emby.Server.Implementations.Social ;
2017-09-09 18:51:24 +00:00
using Emby.Server.Implementations.Threading ;
2017-08-09 19:56:38 +00:00
using Emby.Server.Implementations.TV ;
using Emby.Server.Implementations.Updates ;
2017-09-09 18:51:24 +00:00
using Emby.Server.Implementations.Xml ;
using Emby.Server.MediaEncoding.Subtitles ;
2017-08-09 19:56:38 +00:00
using MediaBrowser.Api ;
2013-03-04 05:43:06 +00:00
using MediaBrowser.Common ;
using MediaBrowser.Common.Configuration ;
2014-04-26 02:55:07 +00:00
using MediaBrowser.Common.Events ;
2015-01-19 06:42:31 +00:00
using MediaBrowser.Common.Extensions ;
2013-03-07 05:34:00 +00:00
using MediaBrowser.Common.Net ;
2017-08-09 19:56:38 +00:00
using MediaBrowser.Common.Plugins ;
2013-12-13 15:48:35 +00:00
using MediaBrowser.Common.Progress ;
2017-08-09 19:56:38 +00:00
using MediaBrowser.Common.Security ;
using MediaBrowser.Common.Updates ;
2013-02-24 21:53:54 +00:00
using MediaBrowser.Controller ;
2014-03-18 01:45:41 +00:00
using MediaBrowser.Controller.Channels ;
2014-06-09 19:16:14 +00:00
using MediaBrowser.Controller.Chapters ;
2014-03-07 15:53:23 +00:00
using MediaBrowser.Controller.Collections ;
2013-03-04 05:43:06 +00:00
using MediaBrowser.Controller.Configuration ;
2014-08-25 03:54:45 +00:00
using MediaBrowser.Controller.Connect ;
2014-10-11 20:38:13 +00:00
using MediaBrowser.Controller.Devices ;
2014-03-13 19:08:02 +00:00
using MediaBrowser.Controller.Dlna ;
2013-03-08 05:08:27 +00:00
using MediaBrowser.Controller.Drawing ;
2013-09-04 17:02:19 +00:00
using MediaBrowser.Controller.Dto ;
2013-03-01 21:22:34 +00:00
using MediaBrowser.Controller.Entities ;
2013-02-27 20:25:45 +00:00
using MediaBrowser.Controller.Library ;
2013-09-26 15:48:14 +00:00
using MediaBrowser.Controller.LiveTv ;
2014-02-20 16:37:41 +00:00
using MediaBrowser.Controller.MediaEncoding ;
2013-12-07 15:52:38 +00:00
using MediaBrowser.Controller.Net ;
2013-07-06 21:23:32 +00:00
using MediaBrowser.Controller.Notifications ;
2013-03-08 05:08:27 +00:00
using MediaBrowser.Controller.Persistence ;
2014-08-02 02:34:45 +00:00
using MediaBrowser.Controller.Playlists ;
2013-03-08 05:08:27 +00:00
using MediaBrowser.Controller.Plugins ;
using MediaBrowser.Controller.Providers ;
2013-03-03 16:53:58 +00:00
using MediaBrowser.Controller.Resolvers ;
2014-05-07 18:38:50 +00:00
using MediaBrowser.Controller.Security ;
2013-05-09 17:38:02 +00:00
using MediaBrowser.Controller.Session ;
2013-03-10 04:22:36 +00:00
using MediaBrowser.Controller.Sorting ;
2014-05-07 02:28:19 +00:00
using MediaBrowser.Controller.Subtitles ;
2014-07-17 22:21:35 +00:00
using MediaBrowser.Controller.Sync ;
2014-09-01 20:10:54 +00:00
using MediaBrowser.Controller.TV ;
2015-05-31 18:22:51 +00:00
using MediaBrowser.LocalMetadata.Savers ;
2017-09-09 18:51:24 +00:00
using MediaBrowser.MediaEncoding.BdInfo ;
2017-08-09 19:56:38 +00:00
using MediaBrowser.Model.Activity ;
using MediaBrowser.Model.Configuration ;
2017-09-09 18:51:24 +00:00
using MediaBrowser.Model.Cryptography ;
2017-08-09 19:56:38 +00:00
using MediaBrowser.Model.Diagnostics ;
using MediaBrowser.Model.Dlna ;
2017-09-09 18:51:24 +00:00
using MediaBrowser.Model.Events ;
2017-08-09 19:56:38 +00:00
using MediaBrowser.Model.Globalization ;
using MediaBrowser.Model.IO ;
2013-09-21 01:04:14 +00:00
using MediaBrowser.Model.Logging ;
2013-02-24 21:53:54 +00:00
using MediaBrowser.Model.MediaInfo ;
2017-08-09 19:56:38 +00:00
using MediaBrowser.Model.Net ;
using MediaBrowser.Model.News ;
using MediaBrowser.Model.Reflection ;
using MediaBrowser.Model.Serialization ;
using MediaBrowser.Model.Services ;
using MediaBrowser.Model.Social ;
2013-02-24 21:53:54 +00:00
using MediaBrowser.Model.System ;
2017-09-09 18:51:24 +00:00
using MediaBrowser.Model.Tasks ;
2017-08-09 19:56:38 +00:00
using MediaBrowser.Model.Text ;
2017-09-09 18:51:24 +00:00
using MediaBrowser.Model.Threading ;
2013-09-14 01:56:03 +00:00
using MediaBrowser.Model.Updates ;
2017-08-09 19:56:38 +00:00
using MediaBrowser.Model.Xml ;
2014-06-09 19:16:14 +00:00
using MediaBrowser.Providers.Chapters ;
2014-01-28 18:37:01 +00:00
using MediaBrowser.Providers.Manager ;
2014-05-07 02:28:19 +00:00
using MediaBrowser.Providers.Subtitles ;
2013-02-28 19:32:41 +00:00
using MediaBrowser.WebDashboard.Api ;
2014-06-30 03:04:50 +00:00
using MediaBrowser.XbmcMetadata.Providers ;
2017-08-09 19:56:38 +00:00
using OpenSubtitlesHandler ;
using ServiceStack ;
2013-02-24 21:53:54 +00:00
using System ;
2015-12-29 03:39:38 +00:00
using System.Collections.Concurrent ;
2013-02-24 21:53:54 +00:00
using System.Collections.Generic ;
2014-01-06 01:59:21 +00:00
using System.Globalization ;
2013-02-24 21:53:54 +00:00
using System.IO ;
using System.Linq ;
2017-08-16 06:43:41 +00:00
using System.Net ;
2013-02-24 21:53:54 +00:00
using System.Reflection ;
2017-08-16 06:43:41 +00:00
using System.Runtime.InteropServices ;
2016-11-11 03:29:51 +00:00
using System.Security.Cryptography.X509Certificates ;
2017-08-16 06:43:41 +00:00
using System.Text ;
2013-09-13 15:02:40 +00:00
using System.Threading ;
2013-02-24 21:53:54 +00:00
using System.Threading.Tasks ;
2016-10-29 04:10:11 +00:00
using StringExtensions = MediaBrowser . Controller . Extensions . StringExtensions ;
2017-09-03 02:42:13 +00:00
using X509Certificate = System . Security . Cryptography . X509Certificates . X509Certificate ;
2013-02-24 21:53:54 +00:00
2017-08-09 19:56:38 +00:00
namespace Emby.Server.Implementations
2013-02-24 21:53:54 +00:00
{
/// <summary>
/// Class CompositionRoot
/// </summary>
2017-09-09 18:51:24 +00:00
public abstract class ApplicationHost : IServerApplicationHost , IDependencyContainer , IDisposable
2013-02-24 21:53:54 +00:00
{
2017-08-16 06:43:41 +00:00
/// <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 abstract bool CanSelfRestart { get ; }
/// <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 virtual bool CanSelfUpdate
{
get
{
return false ;
}
}
/// <summary>
/// Occurs when [has pending restart changed].
/// </summary>
public event EventHandler HasPendingRestartChanged ;
/// <summary>
/// Occurs when [application updated].
/// </summary>
public event EventHandler < GenericEventArgs < PackageVersionInfo > > ApplicationUpdated ;
/// <summary>
/// Gets or sets a value indicating whether this instance has changes that require the entire application to restart.
/// </summary>
/// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value>
public bool HasPendingRestart { get ; private set ; }
2017-09-09 18:51:24 +00:00
public bool IsShuttingDown { get ; private set ; }
2017-08-16 06:43:41 +00:00
/// <summary>
/// Gets or sets the logger.
/// </summary>
/// <value>The logger.</value>
protected ILogger Logger { get ; set ; }
/// <summary>
/// Gets or sets the plugins.
/// </summary>
/// <value>The plugins.</value>
public IPlugin [ ] Plugins { get ; protected set ; }
/// <summary>
/// Gets or sets the log manager.
/// </summary>
/// <value>The log manager.</value>
public ILogManager LogManager { get ; protected set ; }
/// <summary>
/// Gets the application paths.
/// </summary>
/// <value>The application paths.</value>
protected ServerApplicationPaths ApplicationPaths { get ; set ; }
/// <summary>
/// Gets assemblies that failed to load
/// </summary>
/// <value>The failed assemblies.</value>
public List < string > FailedAssemblies { get ; protected set ; }
/// <summary>
/// Gets all concrete types.
/// </summary>
/// <value>All concrete types.</value>
public Type [ ] AllConcreteTypes { get ; protected set ; }
/// <summary>
/// The disposable parts
/// </summary>
protected readonly List < IDisposable > DisposableParts = new List < IDisposable > ( ) ;
/// <summary>
/// Gets a value indicating whether this instance is first run.
/// </summary>
/// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value>
public bool IsFirstRun { get ; private set ; }
/// <summary>
/// Gets the configuration manager.
/// </summary>
/// <value>The configuration manager.</value>
protected IConfigurationManager ConfigurationManager { get ; set ; }
public IFileSystem FileSystemManager { get ; set ; }
protected IEnvironmentInfo EnvironmentInfo { get ; set ; }
2017-08-26 07:03:19 +00:00
private IBlurayExaminer BlurayExaminer { get ; set ; }
2017-08-16 06:43:41 +00:00
public PackageVersionClass SystemUpdateLevel
{
get
{
#if BETA
return PackageVersionClass . Beta ;
#endif
return PackageVersionClass . Release ;
}
}
public virtual string OperatingSystemDisplayName
{
get { return EnvironmentInfo . OperatingSystemName ; }
}
/// <summary>
/// The container
/// </summary>
protected readonly SimpleInjector . Container Container = new SimpleInjector . Container ( ) ;
protected ISystemEvents SystemEvents { get ; set ; }
protected IMemoryStreamFactory MemoryStreamFactory { get ; set ; }
2013-02-24 21:53:54 +00:00
/// <summary>
2013-03-04 05:43:06 +00:00
/// Gets the server configuration manager.
2013-02-24 21:53:54 +00:00
/// </summary>
2013-03-04 05:43:06 +00:00
/// <value>The server configuration manager.</value>
public IServerConfigurationManager ServerConfigurationManager
2013-02-24 21:53:54 +00:00
{
2013-03-04 05:43:06 +00:00
get { return ( IServerConfigurationManager ) ConfigurationManager ; }
2013-03-03 07:27:40 +00:00
}
2013-02-26 17:21:18 +00:00
/// <summary>
2013-03-04 05:43:06 +00:00
/// Gets the configuration manager.
2013-02-26 17:21:18 +00:00
/// </summary>
2013-03-04 05:43:06 +00:00
/// <returns>IConfigurationManager.</returns>
2017-08-16 06:43:41 +00:00
protected IConfigurationManager GetConfigurationManager ( )
2013-02-26 17:21:18 +00:00
{
2015-09-13 23:07:54 +00:00
return new ServerConfigurationManager ( ApplicationPaths , LogManager , XmlSerializer , FileSystemManager ) ;
2013-02-26 17:21:18 +00:00
}
2013-03-08 05:08:27 +00:00
/// <summary>
/// Gets or sets the server manager.
/// </summary>
/// <value>The server manager.</value>
2013-03-07 05:34:00 +00:00
private IServerManager ServerManager { get ; set ; }
2013-03-08 05:08:27 +00:00
/// <summary>
/// Gets or sets the user manager.
/// </summary>
/// <value>The user manager.</value>
public IUserManager UserManager { get ; set ; }
/// <summary>
/// Gets or sets the library manager.
/// </summary>
/// <value>The library manager.</value>
internal ILibraryManager LibraryManager { get ; set ; }
/// <summary>
/// Gets or sets the directory watchers.
/// </summary>
/// <value>The directory watchers.</value>
2014-01-28 21:25:10 +00:00
private ILibraryMonitor LibraryMonitor { get ; set ; }
2013-03-08 05:08:27 +00:00
/// <summary>
/// Gets or sets the provider manager.
/// </summary>
/// <value>The provider manager.</value>
private IProviderManager ProviderManager { get ; set ; }
/// <summary>
/// Gets or sets the HTTP server.
/// </summary>
/// <value>The HTTP server.</value>
private IHttpServer HttpServer { get ; set ; }
2013-09-04 17:02:19 +00:00
private IDtoService DtoService { get ; set ; }
2017-05-12 18:09:42 +00:00
public IImageProcessor ImageProcessor { get ; set ; }
2013-03-10 06:45:16 +00:00
2013-04-08 15:55:53 +00:00
/// <summary>
/// Gets or sets the media encoder.
/// </summary>
/// <value>The media encoder.</value>
2013-04-07 20:55:05 +00:00
private IMediaEncoder MediaEncoder { get ; set ; }
2015-01-02 06:12:58 +00:00
private ISubtitleEncoder SubtitleEncoder { get ; set ; }
2013-04-08 15:55:53 +00:00
2014-08-25 03:54:45 +00:00
private IConnectManager ConnectManager { get ; set ; }
2013-09-24 15:42:30 +00:00
private ISessionManager SessionManager { get ; set ; }
2013-08-10 01:40:52 +00:00
2013-09-26 15:48:14 +00:00
private ILiveTvManager LiveTvManager { get ; set ; }
2013-09-26 21:20:26 +00:00
2014-11-09 18:24:57 +00:00
public ILocalizationManager LocalizationManager { get ; set ; }
2013-06-10 17:46:11 +00:00
2014-02-20 16:37:41 +00:00
private IEncodingManager EncodingManager { get ; set ; }
2014-03-18 17:05:57 +00:00
private IChannelManager ChannelManager { get ; set ; }
2014-07-22 01:29:06 +00:00
private ISyncManager SyncManager { get ; set ; }
2014-02-28 04:49:02 +00:00
2013-04-13 18:02:30 +00:00
/// <summary>
/// Gets or sets the user data repository.
/// </summary>
/// <value>The user data repository.</value>
2013-10-02 16:08:58 +00:00
private IUserDataManager UserDataManager { get ; set ; }
2013-04-19 20:27:02 +00:00
private IUserRepository UserRepository { get ; set ; }
2013-06-18 19:16:27 +00:00
internal IDisplayPreferencesRepository DisplayPreferencesRepository { get ; set ; }
2013-12-16 22:46:40 +00:00
internal IItemRepository ItemRepository { get ; set ; }
2013-07-06 21:23:32 +00:00
private INotificationsRepository NotificationsRepository { get ; set ; }
2013-04-13 18:02:30 +00:00
2014-04-25 20:15:50 +00:00
private INotificationManager NotificationManager { get ; set ; }
2014-05-07 02:28:19 +00:00
private ISubtitleManager SubtitleManager { get ; set ; }
2014-06-09 19:16:14 +00:00
private IChapterManager ChapterManager { get ; set ; }
2014-10-11 20:38:13 +00:00
private IDeviceManager DeviceManager { get ; set ; }
2014-04-25 20:15:50 +00:00
2014-09-01 20:10:54 +00:00
internal IUserViewManager UserViewManager { get ; set ; }
2014-06-07 19:46:24 +00:00
2014-07-08 01:41:03 +00:00
private IAuthenticationRepository AuthenticationRepository { get ; set ; }
2014-09-01 20:10:54 +00:00
private ITVSeriesManager TVSeriesManager { get ; set ; }
2014-10-08 01:37:45 +00:00
private ICollectionManager CollectionManager { get ; set ; }
2015-02-07 21:03:09 +00:00
private IMediaSourceManager MediaSourceManager { get ; set ; }
2015-03-14 04:50:23 +00:00
private IPlaylistManager PlaylistManager { get ; set ; }
2014-07-20 04:46:29 +00:00
2016-10-29 05:40:15 +00:00
/// <summary>
/// Gets or sets the installation manager.
/// </summary>
/// <value>The installation manager.</value>
protected IInstallationManager InstallationManager { get ; private set ; }
/// <summary>
/// Gets the security manager.
/// </summary>
/// <value>The security manager.</value>
protected ISecurityManager SecurityManager { get ; private set ; }
2016-10-28 18:35:17 +00:00
/// <summary>
/// Gets or sets the zip client.
/// </summary>
/// <value>The zip client.</value>
protected IZipClient ZipClient { get ; private set ; }
2016-11-08 18:44:23 +00:00
protected IAuthService AuthService { get ; private set ; }
2016-11-13 04:33:51 +00:00
protected readonly StartupOptions StartupOptions ;
2017-09-09 18:51:24 +00:00
protected readonly string ReleaseAssetFilename ;
2014-09-14 15:26:33 +00:00
2016-11-09 04:58:58 +00:00
internal IPowerManagement PowerManagement { get ; private set ; }
2016-11-11 17:33:10 +00:00
internal IImageEncoder ImageEncoder { get ; private set ; }
2017-08-16 06:43:41 +00:00
protected IProcessFactory ProcessFactory { get ; private set ; }
protected ITimerFactory TimerFactory { get ; private set ; }
protected ICryptoProvider CryptographyProvider = new CryptographyProvider ( ) ;
protected readonly IXmlSerializer XmlSerializer ;
protected ISocketFactory SocketFactory { get ; private set ; }
protected ITaskManager TaskManager { get ; private set ; }
public IHttpClient HttpClient { get ; private set ; }
protected INetworkManager NetworkManager { get ; set ; }
public IJsonSerializer JsonSerializer { get ; private set ; }
protected IIsoManager IsoManager { get ; private set ; }
2016-11-09 04:58:58 +00:00
2013-09-21 01:04:14 +00:00
/// <summary>
2014-07-20 04:46:29 +00:00
/// Initializes a new instance of the <see cref="ApplicationHost" /> class.
2013-09-21 01:04:14 +00:00
/// </summary>
2014-12-22 01:02:15 +00:00
public ApplicationHost ( ServerApplicationPaths applicationPaths ,
ILogManager logManager ,
StartupOptions options ,
2014-10-06 23:58:46 +00:00
IFileSystem fileSystem ,
2016-11-09 04:58:58 +00:00
IPowerManagement powerManagement ,
2016-11-11 08:13:11 +00:00
string releaseAssetFilename ,
2016-11-11 17:33:10 +00:00
IEnvironmentInfo environmentInfo ,
IImageEncoder imageEncoder ,
ISystemEvents systemEvents ,
2017-08-17 20:19:02 +00:00
INetworkManager networkManager )
2013-09-20 17:32:10 +00:00
{
2017-08-16 06:43:41 +00:00
// hack alert, until common can target .net core
BaseExtensions . CryptographyProvider = CryptographyProvider ;
XmlSerializer = new MyXmlSerializer ( fileSystem , logManager . GetLogger ( "XmlSerializer" ) ) ;
NetworkManager = networkManager ;
EnvironmentInfo = environmentInfo ;
SystemEvents = systemEvents ;
2017-08-17 20:19:02 +00:00
MemoryStreamFactory = new MemoryStreamProvider ( ) ;
2017-08-16 06:43:41 +00:00
FailedAssemblies = new List < string > ( ) ;
ApplicationPaths = applicationPaths ;
LogManager = logManager ;
FileSystemManager = fileSystem ;
ConfigurationManager = GetConfigurationManager ( ) ;
// Initialize this early in case the -v command line option is used
Logger = LogManager . GetLogger ( "App" ) ;
2016-11-13 04:33:51 +00:00
StartupOptions = options ;
2017-09-09 18:51:24 +00:00
ReleaseAssetFilename = releaseAssetFilename ;
2016-11-09 04:58:58 +00:00
PowerManagement = powerManagement ;
2014-12-17 22:39:17 +00:00
2016-11-11 17:33:10 +00:00
ImageEncoder = imageEncoder ;
2014-12-17 22:39:17 +00:00
SetBaseExceptionMessage ( ) ;
2017-03-10 19:51:29 +00:00
fileSystem . AddShortcutHandler ( new MbLinkShortcutHandler ( fileSystem ) ) ;
2014-01-30 00:18:05 +00:00
}
2013-09-21 01:04:14 +00:00
2014-11-14 06:27:10 +00:00
private Version _version ;
/// <summary>
/// Gets the current application version
/// </summary>
/// <value>The application version.</value>
2017-08-16 06:43:41 +00:00
public Version ApplicationVersion
2014-11-14 06:27:10 +00:00
{
get
{
2016-11-13 04:33:51 +00:00
return _version ? ? ( _version = GetAssembly ( GetType ( ) ) . GetName ( ) . Version ) ;
2014-11-14 06:27:10 +00:00
}
}
2017-08-16 06:43:41 +00:00
private DeviceId _deviceId ;
public string SystemId
{
get
{
if ( _deviceId = = null )
{
_deviceId = new DeviceId ( ApplicationPaths , LogManager . GetLogger ( "SystemId" ) , FileSystemManager ) ;
}
return _deviceId . Value ;
}
}
2014-01-25 21:07:19 +00:00
/// <summary>
/// Gets the name.
/// </summary>
/// <value>The name.</value>
2017-08-16 06:43:41 +00:00
public string Name
2014-01-25 21:07:19 +00:00
{
get
{
2016-07-14 02:36:42 +00:00
return "Emby Server" ;
2014-01-25 21:07:19 +00:00
}
}
2016-11-11 17:33:10 +00:00
private Assembly GetAssembly ( Type type )
{
return type . GetTypeInfo ( ) . Assembly ;
}
2017-02-19 03:46:09 +00:00
public virtual bool SupportsAutoRunAtStartup
{
get
{
return EnvironmentInfo . OperatingSystem = = MediaBrowser . Model . System . OperatingSystem . Windows ;
}
}
2014-01-06 01:59:21 +00:00
2017-08-16 06:43:41 +00:00
/// <summary>
/// Creates an instance of type and resolves all constructor dependancies
/// </summary>
/// <param name="type">The type.</param>
/// <returns>System.Object.</returns>
public object CreateInstance ( Type type )
{
try
{
return Container . GetInstance ( type ) ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error creating {0}" , ex , type . FullName ) ;
throw ;
}
}
/// <summary>
/// Creates the instance safe.
/// </summary>
/// <param name="type">The type.</param>
/// <returns>System.Object.</returns>
protected object CreateInstanceSafe ( Type type )
{
try
{
return Container . GetInstance ( type ) ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error creating {0}" , ex , type . FullName ) ;
// Don't blow up in release mode
return null ;
}
}
/// <summary>
/// Registers the specified obj.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj">The obj.</param>
/// <param name="manageLifetime">if set to <c>true</c> [manage lifetime].</param>
protected void RegisterSingleInstance < T > ( T obj , bool manageLifetime = true )
where T : class
{
Container . RegisterSingleton ( obj ) ;
if ( manageLifetime )
{
var disposable = obj as IDisposable ;
if ( disposable ! = null )
{
DisposableParts . Add ( disposable ) ;
}
}
}
/// <summary>
/// Registers the single instance.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func">The func.</param>
protected void RegisterSingleInstance < T > ( Func < T > func )
where T : class
{
Container . RegisterSingleton ( func ) ;
}
/// <summary>
/// Resolves this instance.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns>``0.</returns>
public T Resolve < T > ( )
{
return ( T ) Container . GetRegistration ( typeof ( T ) , true ) . GetInstance ( ) ;
}
/// <summary>
/// Resolves this instance.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns>``0.</returns>
public T TryResolve < T > ( )
{
var result = Container . GetRegistration ( typeof ( T ) , false ) ;
if ( result = = null )
{
return default ( T ) ;
}
return ( T ) result . GetInstance ( ) ;
}
/// <summary>
/// Loads the assembly.
/// </summary>
/// <param name="file">The file.</param>
/// <returns>Assembly.</returns>
protected Assembly LoadAssembly ( string file )
{
try
{
return Assembly . Load ( File . ReadAllBytes ( file ) ) ;
}
catch ( Exception ex )
{
FailedAssemblies . Add ( file ) ;
Logger . ErrorException ( "Error loading assembly {0}" , ex , file ) ;
return null ;
}
}
/// <summary>
/// Gets the export types.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns>IEnumerable{Type}.</returns>
public IEnumerable < Type > GetExportTypes < T > ( )
{
var currentType = typeof ( T ) ;
return AllConcreteTypes . Where ( currentType . IsAssignableFrom ) ;
}
/// <summary>
/// Gets the exports.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param>
/// <returns>IEnumerable{``0}.</returns>
public IEnumerable < T > GetExports < T > ( bool manageLiftime = true )
{
var parts = GetExportTypes < T > ( )
. Select ( CreateInstanceSafe )
. Where ( i = > i ! = null )
. Cast < T > ( )
. ToList ( ) ;
if ( manageLiftime )
{
lock ( DisposableParts )
{
DisposableParts . AddRange ( parts . OfType < IDisposable > ( ) ) ;
}
}
return parts ;
}
2014-12-17 22:39:17 +00:00
private void SetBaseExceptionMessage ( )
{
var builder = GetBaseExceptionMessage ( ApplicationPaths ) ;
builder . Insert ( 0 , string . Format ( "Version: {0}{1}" , ApplicationVersion , Environment . NewLine ) ) ;
builder . Insert ( 0 , "*** Error Report ***" + Environment . NewLine ) ;
LogManager . ExceptionMessagePrefix = builder . ToString ( ) ;
}
2013-03-08 05:08:27 +00:00
/// <summary>
2013-03-10 06:45:16 +00:00
/// Runs the startup tasks.
2013-03-08 05:08:27 +00:00
/// </summary>
2017-08-16 06:43:41 +00:00
public async Task RunStartupTasks ( )
2013-03-07 05:34:00 +00:00
{
2017-08-16 06:43:41 +00:00
Resolve < ITaskManager > ( ) . AddTasks ( GetExports < IScheduledTask > ( false ) ) ;
ConfigureAutorun ( ) ;
ConfigurationManager . ConfigurationUpdated + = OnConfigurationUpdated ;
2013-03-08 05:08:27 +00:00
2016-06-30 04:23:52 +00:00
await MediaEncoder . Init ( ) . ConfigureAwait ( false ) ;
2016-06-20 06:19:28 +00:00
2016-09-09 16:58:08 +00:00
if ( string . IsNullOrWhiteSpace ( MediaEncoder . EncoderPath ) )
{
if ( ServerConfigurationManager . Configuration . IsStartupWizardCompleted )
{
ServerConfigurationManager . Configuration . IsStartupWizardCompleted = false ;
ServerConfigurationManager . SaveConfiguration ( ) ;
}
}
2015-12-30 07:11:58 +00:00
Logger . Info ( "ServerId: {0}" , SystemId ) ;
2013-04-08 15:55:53 +00:00
Logger . Info ( "Core startup complete" ) ;
2015-09-13 23:07:54 +00:00
HttpServer . GlobalResponse = null ;
2013-04-08 15:55:53 +00:00
2016-06-29 22:01:35 +00:00
Logger . Info ( "Post-init migrations complete" ) ;
2016-02-03 22:42:33 +00:00
2016-06-29 22:01:35 +00:00
foreach ( var entryPoint in GetExports < IServerEntryPoint > ( ) . ToList ( ) )
2013-06-21 23:38:19 +00:00
{
2016-06-29 22:01:35 +00:00
var name = entryPoint . GetType ( ) . FullName ;
2016-06-30 01:23:58 +00:00
Logger . Info ( "Starting entry point {0}" , name ) ;
2016-09-11 17:09:10 +00:00
var now = DateTime . UtcNow ;
2013-06-21 23:38:19 +00:00
try
{
entryPoint . Run ( ) ;
}
catch ( Exception ex )
{
2016-06-29 22:01:35 +00:00
Logger . ErrorException ( "Error in {0}" , ex , name ) ;
2013-06-21 23:38:19 +00:00
}
2017-08-06 23:01:00 +00:00
Logger . Info ( "Entry point completed: {0}. Duration: {1} seconds" , name , ( DateTime . UtcNow - now ) . TotalSeconds . ToString ( CultureInfo . InvariantCulture ) , "ImageInfos" ) ;
2016-06-29 22:01:35 +00:00
}
2016-06-30 01:23:58 +00:00
Logger . Info ( "All entry points have started" ) ;
2014-01-09 04:44:51 +00:00
LogManager . RemoveConsoleOutput ( ) ;
2013-03-07 05:34:00 +00:00
}
2017-08-16 06:43:41 +00:00
/// <summary>
/// Configures the autorun.
/// </summary>
private void ConfigureAutorun ( )
{
try
{
ConfigureAutoRunAtStartup ( ConfigurationManager . CommonConfiguration . RunAtStartup ) ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error configuring autorun" , ex ) ;
}
}
private IJsonSerializer CreateJsonSerializer ( )
2016-10-08 05:57:38 +00:00
{
2016-10-29 04:10:11 +00:00
try
{
// https://github.com/ServiceStack/ServiceStack/blob/master/tests/ServiceStack.WebHost.IntegrationTests/Web.config#L4
Licensing . RegisterLicense ( "1001-e1JlZjoxMDAxLE5hbWU6VGVzdCBCdXNpbmVzcyxUeXBlOkJ1c2luZXNzLEhhc2g6UHVNTVRPclhvT2ZIbjQ5MG5LZE1mUTd5RUMzQnBucTFEbTE3TDczVEF4QUNMT1FhNXJMOWkzVjFGL2ZkVTE3Q2pDNENqTkQyUktRWmhvUVBhYTBiekJGUUZ3ZE5aZHFDYm9hL3lydGlwUHI5K1JsaTBYbzNsUC85cjVJNHE5QVhldDN6QkE4aTlvdldrdTgyTk1relY2eis2dFFqTThYN2lmc0JveHgycFdjPSxFeHBpcnk6MjAxMy0wMS0wMX0=" ) ;
}
catch
{
// Failing under mono
}
2017-08-16 03:40:36 +00:00
return new JsonSerializer ( FileSystemManager , LogManager . GetLogger ( "JsonSerializer" ) ) ;
2016-10-08 05:57:38 +00:00
}
2017-08-16 06:43:41 +00:00
public async Task Init ( IProgress < double > progress )
2014-02-13 05:11:54 +00:00
{
2015-01-19 04:29:57 +00:00
HttpPort = ServerConfigurationManager . Configuration . HttpServerPortNumber ;
HttpsPort = ServerConfigurationManager . Configuration . HttpsPortNumber ;
2016-11-09 04:58:58 +00:00
// Safeguard against invalid configuration
if ( HttpPort = = HttpsPort )
{
HttpPort = ServerConfiguration . DefaultHttpPort ;
HttpsPort = ServerConfiguration . DefaultHttpsPort ;
}
2017-08-16 06:43:41 +00:00
progress . Report ( 1 ) ;
JsonSerializer = CreateJsonSerializer ( ) ;
OnLoggerLoaded ( true ) ;
LogManager . LoggerLoaded + = ( s , e ) = > OnLoggerLoaded ( false ) ;
IsFirstRun = ! ConfigurationManager . CommonConfiguration . IsStartupWizardCompleted ;
progress . Report ( 2 ) ;
LogManager . LogSeverity = ConfigurationManager . CommonConfiguration . EnableDebugLevelLogging
? LogSeverity . Debug
: LogSeverity . Info ;
progress . Report ( 3 ) ;
DiscoverTypes ( ) ;
progress . Report ( 14 ) ;
SetHttpLimit ( ) ;
progress . Report ( 15 ) ;
var innerProgress = new ActionableProgress < double > ( ) ;
innerProgress . RegisterAction ( p = > progress . Report ( . 8 * p + 15 ) ) ;
await RegisterResources ( innerProgress ) . ConfigureAwait ( false ) ;
FindParts ( ) ;
progress . Report ( 95 ) ;
await InstallIsoMounters ( CancellationToken . None ) . ConfigureAwait ( false ) ;
progress . Report ( 100 ) ;
}
protected virtual void OnLoggerLoaded ( bool isFirstLoad )
{
Logger . Info ( "Application version: {0}" , ApplicationVersion ) ;
if ( ! isFirstLoad )
{
LogEnvironmentInfo ( Logger , ApplicationPaths , false ) ;
}
// Put the app config in the log for troubleshooting purposes
Logger . LogMultiline ( "Application configuration:" , LogSeverity . Info , new StringBuilder ( JsonSerializer . SerializeToString ( ConfigurationManager . CommonConfiguration ) ) ) ;
if ( Plugins ! = null )
{
var pluginBuilder = new StringBuilder ( ) ;
foreach ( var plugin in Plugins )
{
pluginBuilder . AppendLine ( string . Format ( "{0} {1}" , plugin . Name , plugin . Version ) ) ;
}
Logger . LogMultiline ( "Plugins:" , LogSeverity . Info , pluginBuilder ) ;
}
2014-02-13 05:11:54 +00:00
}
2017-02-20 20:50:58 +00:00
protected abstract IConnectManager CreateConnectManager ( ) ;
2017-02-23 19:13:07 +00:00
protected abstract ISyncManager CreateSyncManager ( ) ;
2017-02-20 20:50:58 +00:00
2013-02-24 21:53:54 +00:00
/// <summary>
/// Registers resources that classes will depend on
/// </summary>
2017-08-16 06:43:41 +00:00
protected async Task RegisterResources ( IProgress < double > progress )
2013-02-24 21:53:54 +00:00
{
2017-08-16 06:43:41 +00:00
RegisterSingleInstance ( ConfigurationManager ) ;
RegisterSingleInstance < IApplicationHost > ( this ) ;
RegisterSingleInstance < IApplicationPaths > ( ApplicationPaths ) ;
RegisterSingleInstance ( JsonSerializer ) ;
RegisterSingleInstance ( MemoryStreamFactory ) ;
RegisterSingleInstance ( SystemEvents ) ;
2017-09-05 19:49:02 +00:00
RegisterSingleInstance ( LogManager , false ) ;
2017-08-16 06:43:41 +00:00
RegisterSingleInstance ( Logger ) ;
RegisterSingleInstance ( EnvironmentInfo ) ;
RegisterSingleInstance ( FileSystemManager ) ;
HttpClient = new HttpClientManager . HttpClientManager ( ApplicationPaths , LogManager . GetLogger ( "HttpClient" ) , FileSystemManager , MemoryStreamFactory , GetDefaultUserAgent ) ;
RegisterSingleInstance ( HttpClient ) ;
RegisterSingleInstance ( NetworkManager ) ;
IsoManager = new IsoManager ( ) ;
RegisterSingleInstance ( IsoManager ) ;
TaskManager = new TaskManager ( ApplicationPaths , JsonSerializer , LogManager . GetLogger ( "TaskManager" ) , FileSystemManager , SystemEvents ) ;
RegisterSingleInstance ( TaskManager ) ;
RegisterSingleInstance ( XmlSerializer ) ;
ProcessFactory = new ProcessFactory ( ) ;
RegisterSingleInstance ( ProcessFactory ) ;
TimerFactory = new TimerFactory ( ) ;
RegisterSingleInstance ( TimerFactory ) ;
RegisterSingleInstance ( CryptographyProvider ) ;
SocketFactory = new SocketFactory ( LogManager . GetLogger ( "SocketFactory" ) ) ;
RegisterSingleInstance ( SocketFactory ) ;
2013-02-26 03:43:04 +00:00
2016-11-09 04:58:58 +00:00
RegisterSingleInstance ( PowerManagement ) ;
2016-11-04 08:43:59 +00:00
SecurityManager = new PluginSecurityManager ( this , HttpClient , JsonSerializer , ApplicationPaths , LogManager , FileSystemManager , CryptographyProvider ) ;
2016-10-29 05:40:15 +00:00
RegisterSingleInstance ( SecurityManager ) ;
2017-08-24 19:52:19 +00:00
InstallationManager = new InstallationManager ( LogManager . GetLogger ( "InstallationManager" ) , this , ApplicationPaths , HttpClient , JsonSerializer , SecurityManager , ConfigurationManager , FileSystemManager , CryptographyProvider , PackageRuntime ) ;
2016-10-29 05:40:15 +00:00
RegisterSingleInstance ( InstallationManager ) ;
2016-10-28 18:35:17 +00:00
ZipClient = new ZipClient ( FileSystemManager ) ;
RegisterSingleInstance ( ZipClient ) ;
2016-11-12 06:58:50 +00:00
RegisterSingleInstance < IHttpResultFactory > ( new HttpResultFactory ( LogManager , FileSystemManager , JsonSerializer , MemoryStreamFactory ) ) ;
2013-03-15 04:23:07 +00:00
2013-03-07 05:34:00 +00:00
RegisterSingleInstance < IServerApplicationHost > ( this ) ;
2013-03-04 05:43:06 +00:00
RegisterSingleInstance < IServerApplicationPaths > ( ApplicationPaths ) ;
2013-03-07 05:34:00 +00:00
2013-03-04 05:43:06 +00:00
RegisterSingleInstance ( ServerConfigurationManager ) ;
2015-02-28 18:47:05 +00:00
2016-11-05 02:17:18 +00:00
IAssemblyInfo assemblyInfo = new AssemblyInfo ( ) ;
RegisterSingleInstance < IAssemblyInfo > ( assemblyInfo ) ;
LocalizationManager = new LocalizationManager ( ServerConfigurationManager , FileSystemManager , JsonSerializer , LogManager . GetLogger ( "LocalizationManager" ) , assemblyInfo , new TextLocalizer ( ) ) ;
2016-10-25 19:02:04 +00:00
StringExtensions . LocalizationManager = LocalizationManager ;
2014-03-31 01:00:47 +00:00
RegisterSingleInstance ( LocalizationManager ) ;
2017-08-16 06:43:41 +00:00
ITextEncoding textEncoding = new TextEncoding . TextEncoding ( FileSystemManager , LogManager . GetLogger ( "TextEncoding" ) , JsonSerializer ) ;
2016-10-30 07:11:37 +00:00
RegisterSingleInstance ( textEncoding ) ;
Utilities . EncodingHelper = textEncoding ;
2017-08-26 07:03:19 +00:00
BlurayExaminer = new BdInfoExaminer ( FileSystemManager , textEncoding ) ;
RegisterSingleInstance ( BlurayExaminer ) ;
2013-03-08 05:08:27 +00:00
2016-10-26 02:53:47 +00:00
RegisterSingleInstance < IXmlReaderSettingsFactory > ( new XmlReaderSettingsFactory ( ) ) ;
2014-12-26 17:45:06 +00:00
UserDataManager = new UserDataManager ( LogManager , ServerConfigurationManager ) ;
2013-10-02 16:08:58 +00:00
RegisterSingleInstance ( UserDataManager ) ;
2013-04-13 18:02:30 +00:00
2016-11-18 18:28:45 +00:00
UserRepository = GetUserRepository ( ) ;
2016-12-17 08:27:41 +00:00
// This is only needed for disposal purposes. If removing this, make sure to have the manager handle disposing it
RegisterSingleInstance ( UserRepository ) ;
2016-10-08 05:57:38 +00:00
2016-11-18 09:28:39 +00:00
var displayPreferencesRepo = new SqliteDisplayPreferencesRepository ( LogManager . GetLogger ( "SqliteDisplayPreferencesRepository" ) , JsonSerializer , ApplicationPaths , MemoryStreamFactory ) ;
2016-05-01 21:48:37 +00:00
DisplayPreferencesRepository = displayPreferencesRepo ;
2013-04-19 20:27:02 +00:00
RegisterSingleInstance ( DisplayPreferencesRepository ) ;
2016-11-27 19:36:56 +00:00
var itemRepo = new SqliteItemRepository ( ServerConfigurationManager , JsonSerializer , LogManager . GetLogger ( "SqliteItemRepository" ) , MemoryStreamFactory , assemblyInfo , FileSystemManager , EnvironmentInfo , TimerFactory ) ;
2016-05-01 21:48:37 +00:00
ItemRepository = itemRepo ;
2013-04-19 20:27:02 +00:00
RegisterSingleInstance ( ItemRepository ) ;
2017-05-26 06:48:54 +00:00
AuthenticationRepository = GetAuthenticationRepository ( ) ;
2014-07-08 01:41:03 +00:00
RegisterSingleInstance ( AuthenticationRepository ) ;
2017-08-17 20:19:02 +00:00
UserManager = new UserManager ( LogManager . GetLogger ( "UserManager" ) , ServerConfigurationManager , UserRepository , XmlSerializer , NetworkManager , ( ) = > ImageProcessor , ( ) = > DtoService , ( ) = > ConnectManager , this , JsonSerializer , FileSystemManager , CryptographyProvider ) ;
2013-04-14 03:05:19 +00:00
RegisterSingleInstance ( UserManager ) ;
2015-12-29 03:45:56 +00:00
LibraryManager = new LibraryManager ( Logger , TaskManager , UserManager , ServerConfigurationManager , UserDataManager , ( ) = > LibraryMonitor , FileSystemManager , ( ) = > ProviderManager , ( ) = > UserViewManager ) ;
2013-03-08 05:08:27 +00:00
RegisterSingleInstance ( LibraryManager ) ;
2013-03-05 04:25:27 +00:00
2014-04-02 21:55:19 +00:00
var musicManager = new MusicManager ( LibraryManager ) ;
2014-03-30 16:49:40 +00:00
RegisterSingleInstance < IMusicManager > ( new MusicManager ( LibraryManager ) ) ;
2016-11-04 19:51:59 +00:00
LibraryMonitor = new LibraryMonitor ( LogManager , TaskManager , LibraryManager , ServerConfigurationManager , FileSystemManager , TimerFactory , SystemEvents , EnvironmentInfo ) ;
2014-01-28 21:25:10 +00:00
RegisterSingleInstance ( LibraryMonitor ) ;
2013-03-08 05:08:27 +00:00
2016-11-11 17:33:10 +00:00
ProviderManager = new ProviderManager ( HttpClient , ServerConfigurationManager , LibraryMonitor , LogManager , FileSystemManager , ApplicationPaths , ( ) = > LibraryManager , JsonSerializer , MemoryStreamFactory ) ;
2013-03-08 05:08:27 +00:00
RegisterSingleInstance ( ProviderManager ) ;
2014-01-07 20:12:39 +00:00
RegisterSingleInstance < ISearchEngine > ( ( ) = > new SearchEngine ( LogManager , LibraryManager , UserManager ) ) ;
2013-04-05 19:34:33 +00:00
2017-05-01 02:22:13 +00:00
CertificateInfo = GetCertificateInfo ( true ) ;
Certificate = GetCertificate ( CertificateInfo ) ;
2016-11-12 06:58:50 +00:00
2017-03-12 19:27:26 +00:00
HttpServer = HttpServerFactory . CreateServer ( this , LogManager , ServerConfigurationManager , NetworkManager , MemoryStreamFactory , "Emby" , "web/index.html" , textEncoding , SocketFactory , CryptographyProvider , JsonSerializer , XmlSerializer , EnvironmentInfo , Certificate , FileSystemManager , SupportsDualModeSockets ) ;
2015-09-13 23:07:54 +00:00
HttpServer . GlobalResponse = LocalizationManager . GetLocalizedString ( "StartupEmbyServerIsLoading" ) ;
2013-04-08 16:45:40 +00:00
RegisterSingleInstance ( HttpServer , false ) ;
2013-12-13 15:48:35 +00:00
progress . Report ( 10 ) ;
2013-04-08 16:45:40 +00:00
2017-08-09 19:56:38 +00:00
ServerManager = new ServerManager . ServerManager ( this , JsonSerializer , LogManager . GetLogger ( "ServerManager" ) , ServerConfigurationManager , MemoryStreamFactory , textEncoding ) ;
2013-04-08 15:55:53 +00:00
RegisterSingleInstance ( ServerManager ) ;
2014-03-28 03:32:43 +00:00
var innerProgress = new ActionableProgress < double > ( ) ;
innerProgress . RegisterAction ( p = > progress . Report ( ( . 75 * p ) + 15 ) ) ;
2015-04-29 17:39:23 +00:00
ImageProcessor = GetImageProcessor ( ) ;
2013-09-18 18:49:06 +00:00
RegisterSingleInstance ( ImageProcessor ) ;
2016-07-01 15:51:35 +00:00
TVSeriesManager = new TVSeriesManager ( UserManager , UserDataManager , LibraryManager , ServerConfigurationManager ) ;
2014-12-30 16:36:49 +00:00
RegisterSingleInstance ( TVSeriesManager ) ;
2017-02-23 19:13:07 +00:00
SyncManager = CreateSyncManager ( ) ;
2014-07-22 16:36:34 +00:00
RegisterSingleInstance ( SyncManager ) ;
2015-05-31 18:22:51 +00:00
DtoService = new DtoService ( LogManager . GetLogger ( "DtoService" ) , LibraryManager , UserDataManager , ItemRepository , ImageProcessor , ServerConfigurationManager , FileSystemManager , ProviderManager , ( ) = > ChannelManager , SyncManager , this , ( ) = > DeviceManager , ( ) = > MediaSourceManager , ( ) = > LiveTvManager ) ;
2013-09-04 17:02:19 +00:00
RegisterSingleInstance ( DtoService ) ;
2014-01-18 21:52:01 +00:00
2014-08-25 03:54:45 +00:00
var encryptionManager = new EncryptionManager ( ) ;
RegisterSingleInstance < IEncryptionManager > ( encryptionManager ) ;
2017-02-20 20:50:58 +00:00
ConnectManager = CreateConnectManager ( ) ;
2014-08-25 03:54:45 +00:00
RegisterSingleInstance ( ConnectManager ) ;
2015-12-29 03:45:56 +00:00
DeviceManager = new DeviceManager ( new DeviceRepository ( ApplicationPaths , JsonSerializer , LogManager . GetLogger ( "DeviceManager" ) , FileSystemManager ) , UserManager , FileSystemManager , LibraryMonitor , ServerConfigurationManager , LogManager . GetLogger ( "DeviceManager" ) , NetworkManager ) ;
2014-10-11 20:38:13 +00:00
RegisterSingleInstance ( DeviceManager ) ;
2016-11-02 20:53:50 +00:00
var newsService = new Emby . Server . Implementations . News . NewsService ( ApplicationPaths , JsonSerializer ) ;
2014-01-18 21:52:01 +00:00
RegisterSingleInstance < INewsService > ( newsService ) ;
2013-12-13 15:48:35 +00:00
progress . Report ( 15 ) ;
2015-10-17 15:05:12 +00:00
ChannelManager = new ChannelManager ( UserManager , DtoService , LibraryManager , LogManager . GetLogger ( "ChannelManager" ) , ServerConfigurationManager , FileSystemManager , UserDataManager , JsonSerializer , LocalizationManager , HttpClient , ProviderManager ) ;
2014-03-18 17:05:57 +00:00
RegisterSingleInstance ( ChannelManager ) ;
2014-03-18 01:45:41 +00:00
2016-11-03 06:37:52 +00:00
MediaSourceManager = new MediaSourceManager ( ItemRepository , UserManager , LibraryManager , LogManager . GetLogger ( "MediaSourceManager" ) , JsonSerializer , FileSystemManager , UserDataManager , TimerFactory ) ;
2015-03-07 22:43:53 +00:00
RegisterSingleInstance ( MediaSourceManager ) ;
2016-11-03 23:35:19 +00:00
SessionManager = new SessionManager ( UserDataManager , LogManager . GetLogger ( "SessionManager" ) , LibraryManager , UserManager , musicManager , DtoService , ImageProcessor , JsonSerializer , this , HttpClient , AuthenticationRepository , DeviceManager , MediaSourceManager , TimerFactory ) ;
2015-03-08 18:11:53 +00:00
RegisterSingleInstance ( SessionManager ) ;
2016-11-04 08:31:05 +00:00
var dlnaManager = new DlnaManager ( XmlSerializer , FileSystemManager , ApplicationPaths , LogManager . GetLogger ( "Dlna" ) , JsonSerializer , this , assemblyInfo ) ;
2014-03-13 19:08:02 +00:00
RegisterSingleInstance < IDlnaManager > ( dlnaManager ) ;
2016-11-04 08:31:05 +00:00
var connectionManager = new ConnectionManager ( dlnaManager , ServerConfigurationManager , LogManager . GetLogger ( "UpnpConnectionManager" ) , HttpClient , new XmlReaderSettingsFactory ( ) ) ;
2014-05-21 00:56:24 +00:00
RegisterSingleInstance < IConnectionManager > ( connectionManager ) ;
2015-09-29 16:29:06 +00:00
CollectionManager = new CollectionManager ( LibraryManager , FileSystemManager , LibraryMonitor , LogManager . GetLogger ( "CollectionManager" ) , ProviderManager ) ;
2014-10-08 01:37:45 +00:00
RegisterSingleInstance ( CollectionManager ) ;
2014-03-07 15:53:23 +00:00
2015-07-24 15:20:11 +00:00
PlaylistManager = new PlaylistManager ( LibraryManager , FileSystemManager , LibraryMonitor , LogManager . GetLogger ( "PlaylistManager" ) , UserManager , ProviderManager ) ;
2015-03-14 04:50:23 +00:00
RegisterSingleInstance < IPlaylistManager > ( PlaylistManager ) ;
2014-08-02 02:34:45 +00:00
2016-09-06 05:02:05 +00:00
LiveTvManager = new LiveTvManager ( this , ServerConfigurationManager , Logger , ItemRepository , ImageProcessor , UserDataManager , DtoService , UserManager , LibraryManager , TaskManager , LocalizationManager , JsonSerializer , ProviderManager , FileSystemManager , SecurityManager ) ;
2014-01-12 06:31:21 +00:00
RegisterSingleInstance ( LiveTvManager ) ;
2015-10-04 22:04:56 +00:00
UserViewManager = new UserViewManager ( LibraryManager , LocalizationManager , UserManager , ChannelManager , LiveTvManager , ServerConfigurationManager ) ;
2014-06-07 19:46:24 +00:00
RegisterSingleInstance ( UserViewManager ) ;
2017-08-02 07:30:17 +00:00
var contentDirectory = new ContentDirectory ( dlnaManager , UserDataManager , ImageProcessor , LibraryManager , ServerConfigurationManager , UserManager , LogManager . GetLogger ( "UpnpContentDirectory" ) , HttpClient , LocalizationManager , ChannelManager , MediaSourceManager , UserViewManager , ( ) = > MediaEncoder , new XmlReaderSettingsFactory ( ) , TVSeriesManager ) ;
2014-07-30 03:31:35 +00:00
RegisterSingleInstance < IContentDirectory > ( contentDirectory ) ;
2016-11-04 08:31:05 +00:00
var mediaRegistrar = new MediaReceiverRegistrar ( LogManager . GetLogger ( "MediaReceiverRegistrar" ) , HttpClient , ServerConfigurationManager , new XmlReaderSettingsFactory ( ) ) ;
2015-01-30 17:58:38 +00:00
RegisterSingleInstance < IMediaReceiverRegistrar > ( mediaRegistrar ) ;
2014-04-27 03:42:05 +00:00
NotificationManager = new NotificationManager ( LogManager , UserManager , ServerConfigurationManager ) ;
2014-04-25 20:15:50 +00:00
RegisterSingleInstance ( NotificationManager ) ;
2015-02-07 21:03:09 +00:00
SubtitleManager = new SubtitleManager ( LogManager . GetLogger ( "SubtitleManager" ) , FileSystemManager , LibraryMonitor , LibraryManager , MediaSourceManager ) ;
2014-05-07 02:28:19 +00:00
RegisterSingleInstance ( SubtitleManager ) ;
2016-11-04 08:31:05 +00:00
RegisterSingleInstance < IDeviceDiscovery > ( new DeviceDiscovery ( LogManager . GetLogger ( "IDeviceDiscovery" ) , ServerConfigurationManager , SocketFactory , TimerFactory ) ) ;
2015-07-23 16:32:34 +00:00
2014-06-10 17:36:06 +00:00
ChapterManager = new ChapterManager ( LibraryManager , LogManager . GetLogger ( "ChapterManager" ) , ServerConfigurationManager , ItemRepository ) ;
2014-06-09 19:16:14 +00:00
RegisterSingleInstance ( ChapterManager ) ;
2015-01-02 05:36:27 +00:00
await RegisterMediaEncoder ( innerProgress ) . ConfigureAwait ( false ) ;
progress . Report ( 90 ) ;
2016-08-30 06:06:24 +00:00
EncodingManager = new EncodingManager ( FileSystemManager , Logger , MediaEncoder , ChapterManager , LibraryManager ) ;
2014-06-10 17:36:06 +00:00
RegisterSingleInstance ( EncodingManager ) ;
2016-11-18 08:39:20 +00:00
var sharingRepo = new SharingRepository ( LogManager . GetLogger ( "SharingRepository" ) , ApplicationPaths ) ;
sharingRepo . Initialize ( ) ;
2016-12-17 08:27:41 +00:00
// This is only needed for disposal purposes. If removing this, make sure to have the manager handle disposing it
RegisterSingleInstance < ISharingRepository > ( sharingRepo ) ;
2015-06-30 23:59:45 +00:00
RegisterSingleInstance < ISharingManager > ( new SharingManager ( sharingRepo , ServerConfigurationManager , LibraryManager , this ) ) ;
2015-08-10 17:37:50 +00:00
2016-11-18 08:39:20 +00:00
var activityLogRepo = GetActivityLogRepository ( ) ;
2014-08-10 22:13:17 +00:00
RegisterSingleInstance ( activityLogRepo ) ;
2014-10-02 00:28:16 +00:00
RegisterSingleInstance < IActivityManager > ( new ActivityManager ( LogManager . GetLogger ( "ActivityManager" ) , activityLogRepo , UserManager ) ) ;
2014-08-10 22:13:17 +00:00
2015-04-04 00:41:16 +00:00
var authContext = new AuthorizationContext ( AuthenticationRepository , ConnectManager ) ;
2014-07-02 04:57:18 +00:00
RegisterSingleInstance < IAuthorizationContext > ( authContext ) ;
RegisterSingleInstance < ISessionContext > ( new SessionContext ( UserManager , authContext , SessionManager ) ) ;
2016-11-08 18:44:23 +00:00
AuthService = new AuthService ( UserManager , authContext , ServerConfigurationManager , ConnectManager , SessionManager , DeviceManager ) ;
RegisterSingleInstance < IAuthService > ( AuthService ) ;
2014-07-02 04:57:18 +00:00
2016-11-11 17:33:10 +00:00
SubtitleEncoder = new SubtitleEncoder ( LibraryManager , LogManager . GetLogger ( "SubtitleEncoder" ) , ApplicationPaths , FileSystemManager , MediaEncoder , JsonSerializer , HttpClient , MediaSourceManager , MemoryStreamFactory , ProcessFactory , textEncoding ) ;
2015-01-02 06:12:58 +00:00
RegisterSingleInstance ( SubtitleEncoder ) ;
2016-06-04 05:51:33 +00:00
2016-11-18 09:28:39 +00:00
displayPreferencesRepo . Initialize ( ) ;
2016-06-24 06:32:51 +00:00
2016-11-21 20:22:43 +00:00
var userDataRepo = new SqliteUserDataRepository ( LogManager . GetLogger ( "SqliteUserDataRepository" ) , ApplicationPaths , FileSystemManager ) ;
2016-06-24 06:32:51 +00:00
( ( UserDataManager ) UserDataManager ) . Repository = userDataRepo ;
2016-11-20 09:46:07 +00:00
itemRepo . Initialize ( userDataRepo ) ;
2016-05-01 21:48:37 +00:00
( ( LibraryManager ) LibraryManager ) . ItemRepository = ItemRepository ;
2016-11-18 08:39:20 +00:00
ConfigureNotificationsRepository ( ) ;
2013-12-13 15:48:35 +00:00
progress . Report ( 100 ) ;
2013-04-08 15:55:53 +00:00
2014-02-22 21:05:56 +00:00
SetStaticProperties ( ) ;
2017-08-27 00:32:33 +00:00
( ( UserManager ) UserManager ) . Initialize ( ) ;
2013-03-08 05:08:27 +00:00
}
2017-09-12 06:27:39 +00:00
public virtual string PackageRuntime
2017-08-24 19:52:19 +00:00
{
get
{
return "netframework" ;
}
}
2017-08-16 06:43:41 +00:00
public static void LogEnvironmentInfo ( ILogger logger , IApplicationPaths appPaths , bool isStartup )
{
logger . LogMultiline ( "Emby" , LogSeverity . Info , GetBaseExceptionMessage ( appPaths ) ) ;
}
protected static StringBuilder GetBaseExceptionMessage ( IApplicationPaths appPaths )
{
var builder = new StringBuilder ( ) ;
builder . AppendLine ( string . Format ( "Command line: {0}" , string . Join ( " " , Environment . GetCommandLineArgs ( ) ) ) ) ;
builder . AppendLine ( string . Format ( "Operating system: {0}" , Environment . OSVersion ) ) ;
builder . AppendLine ( string . Format ( "64-Bit OS: {0}" , Environment . Is64BitOperatingSystem ) ) ;
builder . AppendLine ( string . Format ( "64-Bit Process: {0}" , Environment . Is64BitProcess ) ) ;
2017-09-02 19:22:19 +00:00
builder . AppendLine ( string . Format ( "User Interactive: {0}" , Environment . UserInteractive ) ) ;
2017-08-16 06:43:41 +00:00
Type type = Type . GetType ( "Mono.Runtime" ) ;
if ( type ! = null )
{
MethodInfo displayName = type . GetMethod ( "GetDisplayName" , BindingFlags . NonPublic | BindingFlags . Static ) ;
if ( displayName ! = null )
{
builder . AppendLine ( "Mono: " + displayName . Invoke ( null , null ) ) ;
}
}
builder . AppendLine ( string . Format ( "Processor count: {0}" , Environment . ProcessorCount ) ) ;
builder . AppendLine ( string . Format ( "Program data path: {0}" , appPaths . ProgramDataPath ) ) ;
builder . AppendLine ( string . Format ( "Application directory: {0}" , appPaths . ProgramSystemPath ) ) ;
return builder ;
}
private void SetHttpLimit ( )
{
try
{
// Increase the max http request limit
ServicePointManager . DefaultConnectionLimit = Math . Max ( 96 , ServicePointManager . DefaultConnectionLimit ) ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error setting http limit" , ex ) ;
}
}
/// <summary>
/// Installs the iso mounters.
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
private async Task InstallIsoMounters ( CancellationToken cancellationToken )
{
var list = new List < IIsoMounter > ( ) ;
foreach ( var isoMounter in GetExports < IIsoMounter > ( ) )
{
try
{
if ( isoMounter . RequiresInstallation & & ! isoMounter . IsInstalled )
{
Logger . Info ( "Installing {0}" , isoMounter . Name ) ;
await isoMounter . Install ( cancellationToken ) . ConfigureAwait ( false ) ;
}
list . Add ( isoMounter ) ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "{0} failed to load." , ex , isoMounter . Name ) ;
}
}
IsoManager . AddParts ( list ) ;
}
private string GetDefaultUserAgent ( )
{
var name = FormatAttribute ( Name ) ;
return name + "/" + ApplicationVersion ;
}
private string FormatAttribute ( string str )
{
var arr = str . ToCharArray ( ) ;
arr = Array . FindAll < char > ( arr , ( c = > ( char . IsLetterOrDigit ( c )
| | char . IsWhiteSpace ( c ) ) ) ) ;
var result = new string ( arr ) ;
if ( string . IsNullOrWhiteSpace ( result ) )
{
result = "Emby" ;
}
return result ;
}
2017-02-19 03:46:09 +00:00
protected virtual bool SupportsDualModeSockets
{
get
{
return true ;
}
}
2016-11-19 05:52:49 +00:00
2017-09-03 02:42:13 +00:00
private X509Certificate GetCertificate ( CertificateInfo info )
2016-11-11 03:29:51 +00:00
{
2017-05-01 02:22:13 +00:00
var certificateLocation = info = = null ? null : info . Path ;
2016-11-11 03:29:51 +00:00
if ( string . IsNullOrWhiteSpace ( certificateLocation ) )
{
return null ;
}
try
{
2016-11-13 21:04:21 +00:00
if ( ! FileSystemManager . FileExists ( certificateLocation ) )
{
return null ;
}
2017-05-10 19:12:03 +00:00
// Don't use an empty string password
var password = string . IsNullOrWhiteSpace ( info . Password ) ? null : info . Password ;
X509Certificate2 localCert = new X509Certificate2 ( certificateLocation , password ) ;
2016-11-11 03:29:51 +00:00
//localCert.PrivateKey = PrivateKey.CreateFromFile(pvk_file).RSA;
2016-11-11 17:33:10 +00:00
if ( ! localCert . HasPrivateKey )
2016-11-11 03:29:51 +00:00
{
//throw new FileNotFoundException("Secure requested, no private key included", certificateLocation);
return null ;
}
2017-09-03 02:42:13 +00:00
return localCert ;
2016-11-11 03:29:51 +00:00
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error loading cert from {0}" , ex , certificateLocation ) ;
return null ;
}
}
2015-04-29 17:39:23 +00:00
private IImageProcessor GetImageProcessor ( )
{
2017-08-26 06:18:52 +00:00
return new ImageProcessor ( LogManager . GetLogger ( "ImageProcessor" ) , ServerConfigurationManager . ApplicationPaths , FileSystemManager , JsonSerializer , ImageEncoder , ( ) = > LibraryManager , TimerFactory , ( ) = > MediaEncoder ) ;
2013-10-05 17:13:32 +00:00
}
2017-02-19 03:46:09 +00:00
protected virtual 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 ( EnvironmentInfo . OperatingSystem = = MediaBrowser . Model . System . OperatingSystem . Linux )
{
info . FFMpegFilename = "ffmpeg" ;
info . FFProbeFilename = "ffprobe" ;
info . ArchiveType = "7z" ;
2017-03-10 18:33:17 +00:00
info . Version = "20170308" ;
2017-02-19 03:46:09 +00:00
info . DownloadUrls = GetLinuxDownloadUrls ( ) ;
}
else if ( EnvironmentInfo . OperatingSystem = = MediaBrowser . Model . System . OperatingSystem . Windows )
{
info . FFMpegFilename = "ffmpeg.exe" ;
info . FFProbeFilename = "ffprobe.exe" ;
2017-03-10 18:33:17 +00:00
info . Version = "20170308" ;
2017-02-19 03:46:09 +00:00
info . ArchiveType = "7z" ;
info . DownloadUrls = GetWindowsDownloadUrls ( ) ;
}
2017-03-10 18:33:17 +00:00
else if ( EnvironmentInfo . OperatingSystem = = MediaBrowser . Model . System . OperatingSystem . OSX )
{
info . FFMpegFilename = "ffmpeg" ;
info . FFProbeFilename = "ffprobe" ;
info . ArchiveType = "7z" ;
info . Version = "20170308" ;
info . DownloadUrls = GetMacDownloadUrls ( ) ;
}
2017-02-20 21:00:36 +00:00
else
{
// No version available - user requirement
info . DownloadUrls = new string [ ] { } ;
}
2017-02-19 03:46:09 +00:00
return info ;
}
2017-03-10 18:33:17 +00:00
private string [ ] GetMacDownloadUrls ( )
{
switch ( EnvironmentInfo . SystemArchitecture )
{
2017-08-16 17:30:16 +00:00
case MediaBrowser . Model . System . Architecture . X64 :
2017-03-10 18:33:17 +00:00
return new [ ]
{
2017-08-17 20:19:02 +00:00
"https://embydata.com/downloads/ffmpeg/osx/ffmpeg-x64-20170308.7z"
2017-03-10 18:33:17 +00:00
} ;
}
return new string [ ] { } ;
}
2017-02-19 03:46:09 +00:00
private string [ ] GetWindowsDownloadUrls ( )
{
switch ( EnvironmentInfo . SystemArchitecture )
{
2017-08-16 17:30:16 +00:00
case MediaBrowser . Model . System . Architecture . X64 :
2017-02-19 03:46:09 +00:00
return new [ ]
{
2017-08-17 20:19:02 +00:00
"https://embydata.com/downloads/ffmpeg/windows/ffmpeg-20170308-win64.7z"
2017-02-19 03:46:09 +00:00
} ;
2017-08-16 17:30:16 +00:00
case MediaBrowser . Model . System . Architecture . X86 :
2017-02-19 03:46:09 +00:00
return new [ ]
{
2017-08-17 20:19:02 +00:00
"https://embydata.com/downloads/ffmpeg/windows/ffmpeg-20170308-win32.7z"
2017-02-19 03:46:09 +00:00
} ;
}
return new string [ ] { } ;
}
private string [ ] GetLinuxDownloadUrls ( )
{
switch ( EnvironmentInfo . SystemArchitecture )
{
2017-08-16 17:30:16 +00:00
case MediaBrowser . Model . System . Architecture . X64 :
2017-02-19 03:46:09 +00:00
return new [ ]
{
2017-08-17 20:19:02 +00:00
"https://embydata.com/downloads/ffmpeg/linux/ffmpeg-git-20170301-64bit-static.7z"
2017-02-19 03:46:09 +00:00
} ;
2017-08-16 17:30:16 +00:00
case MediaBrowser . Model . System . Architecture . X86 :
2017-02-19 03:46:09 +00:00
return new [ ]
{
2017-08-17 20:19:02 +00:00
"https://embydata.com/downloads/ffmpeg/linux/ffmpeg-git-20170301-32bit-static.7z"
2017-02-19 03:46:09 +00:00
} ;
}
return new string [ ] { } ;
}
2016-11-13 04:33:51 +00:00
2013-09-23 15:37:50 +00:00
/// <summary>
/// Registers the media encoder.
/// </summary>
/// <returns>Task.</returns>
2013-12-13 15:48:35 +00:00
private async Task RegisterMediaEncoder ( IProgress < double > progress )
2013-09-23 15:37:50 +00:00
{
2016-06-23 17:04:18 +00:00
string encoderPath = null ;
string probePath = null ;
2016-11-13 04:33:51 +00:00
var info = await new FFMpegLoader ( Logger , ApplicationPaths , HttpClient , ZipClient , FileSystemManager , GetFfmpegInstallInfo ( ) )
. GetFFMpegInfo ( StartupOptions , progress ) . ConfigureAwait ( false ) ;
2013-09-23 15:37:50 +00:00
2016-06-23 17:04:18 +00:00
encoderPath = info . EncoderPath ;
probePath = info . ProbePath ;
2016-06-29 05:49:31 +00:00
var hasExternalEncoder = string . Equals ( info . Version , "external" , StringComparison . OrdinalIgnoreCase ) ;
2016-06-20 06:19:28 +00:00
2017-08-09 19:56:38 +00:00
var mediaEncoder = new MediaEncoding . Encoder . MediaEncoder ( LogManager . GetLogger ( "MediaEncoder" ) ,
2015-01-19 04:29:57 +00:00
JsonSerializer ,
2016-06-23 17:04:18 +00:00
encoderPath ,
probePath ,
2016-06-29 05:49:31 +00:00
hasExternalEncoder ,
2015-01-02 05:36:27 +00:00
ServerConfigurationManager ,
FileSystemManager ,
LiveTvManager ,
IsoManager ,
LibraryManager ,
ChannelManager ,
2015-01-02 06:12:58 +00:00
SessionManager ,
2015-03-08 04:44:31 +00:00
( ) = > SubtitleEncoder ,
2016-07-03 02:47:39 +00:00
( ) = > MediaSourceManager ,
HttpClient ,
2016-11-18 08:39:20 +00:00
ZipClient ,
2016-11-11 17:33:10 +00:00
MemoryStreamFactory ,
2016-11-01 04:07:12 +00:00
ProcessFactory ,
2016-11-11 17:33:10 +00:00
( Environment . ProcessorCount > 2 ? 14000 : 40000 ) ,
2016-11-29 19:13:20 +00:00
EnvironmentInfo . OperatingSystem = = MediaBrowser . Model . System . OperatingSystem . Windows ,
2017-08-26 07:03:19 +00:00
EnvironmentInfo ,
BlurayExaminer ) ;
2015-09-18 03:08:45 +00:00
MediaEncoder = mediaEncoder ;
2013-09-23 15:37:50 +00:00
RegisterSingleInstance ( MediaEncoder ) ;
}
2013-09-30 22:18:44 +00:00
/// <summary>
/// Gets the user repository.
/// </summary>
/// <returns>Task{IUserRepository}.</returns>
2016-11-18 18:28:45 +00:00
private IUserRepository GetUserRepository ( )
2013-08-10 00:46:34 +00:00
{
2016-11-18 18:28:45 +00:00
var repo = new SqliteUserRepository ( LogManager . GetLogger ( "SqliteUserRepository" ) , ApplicationPaths , JsonSerializer , MemoryStreamFactory ) ;
2013-08-10 00:46:34 +00:00
2016-11-18 18:28:45 +00:00
repo . Initialize ( ) ;
2013-08-18 19:44:38 +00:00
2016-10-07 15:08:13 +00:00
return repo ;
2014-01-20 16:09:53 +00:00
}
2017-05-26 06:48:54 +00:00
private IAuthenticationRepository GetAuthenticationRepository ( )
2014-07-08 01:41:03 +00:00
{
2016-11-18 09:28:39 +00:00
var repo = new AuthenticationRepository ( LogManager . GetLogger ( "AuthenticationRepository" ) , ServerConfigurationManager . ApplicationPaths ) ;
2014-07-08 01:41:03 +00:00
2016-11-18 09:28:39 +00:00
repo . Initialize ( ) ;
2014-07-08 01:41:03 +00:00
return repo ;
}
2016-11-18 08:39:20 +00:00
private IActivityRepository GetActivityLogRepository ( )
2014-08-10 22:13:17 +00:00
{
2016-11-18 08:39:20 +00:00
var repo = new ActivityRepository ( LogManager . GetLogger ( "ActivityRepository" ) , ServerConfigurationManager . ApplicationPaths ) ;
2014-08-10 22:13:17 +00:00
2016-11-18 08:39:20 +00:00
repo . Initialize ( ) ;
2014-08-10 22:13:17 +00:00
return repo ;
}
2013-07-06 21:23:32 +00:00
/// <summary>
/// Configures the repositories.
/// </summary>
2016-11-18 08:39:20 +00:00
private void ConfigureNotificationsRepository ( )
2013-07-06 21:23:32 +00:00
{
2017-02-17 21:11:13 +00:00
var repo = new SqliteNotificationsRepository ( LogManager . GetLogger ( "SqliteNotificationsRepository" ) , ServerConfigurationManager . ApplicationPaths , FileSystemManager ) ;
2013-07-06 21:23:32 +00:00
2016-11-18 08:39:20 +00:00
repo . Initialize ( ) ;
2013-07-06 21:23:32 +00:00
NotificationsRepository = repo ;
RegisterSingleInstance ( NotificationsRepository ) ;
}
2013-09-05 17:26:03 +00:00
2013-03-08 05:08:27 +00:00
/// <summary>
/// Dirty hacks
/// </summary>
private void SetStaticProperties ( )
{
// For now there's no real way to inject these properly
BaseItem . Logger = LogManager . GetLogger ( "BaseItem" ) ;
BaseItem . ConfigurationManager = ServerConfigurationManager ;
BaseItem . LibraryManager = LibraryManager ;
BaseItem . ProviderManager = ProviderManager ;
2013-06-10 17:46:11 +00:00
BaseItem . LocalizationManager = LocalizationManager ;
2013-06-20 16:44:24 +00:00
BaseItem . ItemRepository = ItemRepository ;
2013-03-08 05:08:27 +00:00
User . XmlSerializer = XmlSerializer ;
User . UserManager = UserManager ;
2013-10-06 01:04:41 +00:00
Folder . UserManager = UserManager ;
2013-10-30 15:07:30 +00:00
BaseItem . FileSystem = FileSystemManager ;
2014-01-16 17:23:30 +00:00
BaseItem . UserDataManager = UserDataManager ;
2014-09-01 20:10:54 +00:00
BaseItem . ChannelManager = ChannelManager ;
2014-08-14 13:24:30 +00:00
BaseItem . LiveTvManager = LiveTvManager ;
2014-09-01 20:10:54 +00:00
Folder . UserViewManager = UserViewManager ;
UserView . TVSeriesManager = TVSeriesManager ;
2015-03-14 04:50:23 +00:00
UserView . PlaylistManager = PlaylistManager ;
2014-10-08 01:37:45 +00:00
BaseItem . CollectionManager = CollectionManager ;
2015-02-07 21:03:09 +00:00
BaseItem . MediaSourceManager = MediaSourceManager ;
2016-08-13 05:49:00 +00:00
CollectionFolder . XmlSerializer = XmlSerializer ;
2016-10-27 22:54:56 +00:00
Utilities . CryptographyProvider = CryptographyProvider ;
2016-11-08 18:44:23 +00:00
AuthenticatedAttribute . AuthService = AuthService ;
2013-02-24 21:53:54 +00:00
}
2013-03-01 21:22:34 +00:00
/// <summary>
/// Finds the parts.
/// </summary>
2017-08-16 06:43:41 +00:00
protected void FindParts ( )
2013-03-01 21:22:34 +00:00
{
2016-10-10 18:18:28 +00:00
if ( ! ServerConfigurationManager . Configuration . IsPortAuthorized )
2013-03-27 22:13:46 +00:00
{
RegisterServerWithAdministratorAccess ( ) ;
2015-01-12 05:07:19 +00:00
ServerConfigurationManager . Configuration . IsPortAuthorized = true ;
ConfigurationManager . SaveConfiguration ( ) ;
2013-03-27 22:13:46 +00:00
}
2016-10-29 04:10:11 +00:00
RegisterModules ( ) ;
2017-08-16 06:43:41 +00:00
ConfigurationManager . AddParts ( GetExports < IConfigurationFactory > ( ) ) ;
Plugins = GetExports < IPlugin > ( ) . Select ( LoadPlugin ) . Where ( i = > i ! = null ) . ToArray ( ) ;
2013-03-15 04:23:07 +00:00
2016-10-26 06:01:42 +00:00
HttpServer . Init ( GetExports < IService > ( false ) ) ;
2013-04-08 15:55:53 +00:00
2013-05-17 15:29:22 +00:00
ServerManager . AddWebSocketListeners ( GetExports < IWebSocketListener > ( false ) ) ;
2013-03-08 05:08:27 +00:00
2014-12-27 22:52:41 +00:00
StartServer ( ) ;
2013-03-07 05:34:00 +00:00
2013-06-03 18:15:35 +00:00
LibraryManager . AddParts ( GetExports < IResolverIgnoreRule > ( ) ,
2017-08-17 20:19:02 +00:00
GetExports < IVirtualFolderCreator > ( ) ,
GetExports < IItemResolver > ( ) ,
GetExports < IIntroProvider > ( ) ,
GetExports < IBaseItemComparer > ( ) ,
GetExports < ILibraryPostScanTask > ( ) ) ;
2013-06-25 01:22:21 +00:00
2014-05-05 19:53:05 +00:00
ProviderManager . AddParts ( GetExports < IImageProvider > ( ) ,
2017-08-17 20:19:02 +00:00
GetExports < IMetadataService > ( ) ,
GetExports < IMetadataProvider > ( ) ,
GetExports < IMetadataSaver > ( ) ,
GetExports < IExternalId > ( ) ) ;
2013-08-10 01:40:52 +00:00
2013-09-20 00:53:18 +00:00
ImageProcessor . AddParts ( GetExports < IImageEnhancer > ( ) ) ;
2013-09-26 16:17:36 +00:00
2015-07-23 13:23:22 +00:00
LiveTvManager . AddParts ( GetExports < ILiveTvService > ( ) , GetExports < ITunerHost > ( ) , GetExports < IListingsProvider > ( ) ) ;
2013-12-25 14:39:46 +00:00
2014-05-07 02:28:19 +00:00
SubtitleManager . AddParts ( GetExports < ISubtitleProvider > ( ) ) ;
2014-06-11 14:42:03 +00:00
2013-12-25 14:39:46 +00:00
SessionManager . AddParts ( GetExports < ISessionControllerFactory > ( ) ) ;
2014-03-18 17:05:57 +00:00
2015-09-16 03:55:26 +00:00
ChannelManager . AddParts ( GetExports < IChannel > ( ) ) ;
2014-04-25 20:15:50 +00:00
2015-03-07 22:43:53 +00:00
MediaSourceManager . AddParts ( GetExports < IMediaSourceProvider > ( ) ) ;
2015-04-04 00:41:16 +00:00
2014-04-27 03:42:05 +00:00
NotificationManager . AddParts ( GetExports < INotificationService > ( ) , GetExports < INotificationTypeFactory > ( ) ) ;
2014-07-22 01:29:06 +00:00
SyncManager . AddParts ( GetExports < ISyncProvider > ( ) ) ;
2013-03-01 21:22:34 +00:00
}
2017-08-16 06:43:41 +00:00
private IPlugin LoadPlugin ( IPlugin plugin )
{
try
{
var assemblyPlugin = plugin as IPluginAssembly ;
if ( assemblyPlugin ! = null )
{
var assembly = plugin . GetType ( ) . Assembly ;
var assemblyName = assembly . GetName ( ) ;
var assemblyFileName = assemblyName . Name + ".dll" ;
var assemblyFilePath = Path . Combine ( ApplicationPaths . PluginsPath , assemblyFileName ) ;
2017-08-28 16:41:32 +00:00
assemblyPlugin . SetAttributes ( assemblyFilePath , assemblyFileName , assemblyName . Version ) ;
try
{
var idAttributes = assembly . GetCustomAttributes ( typeof ( GuidAttribute ) , true ) ;
if ( idAttributes . Length > 0 )
{
var attribute = ( GuidAttribute ) idAttributes [ 0 ] ;
var assemblyId = new Guid ( attribute . Value ) ;
assemblyPlugin . SetId ( assemblyId ) ;
}
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error getting plugin Id from {0}." , ex , plugin . GetType ( ) . FullName ) ;
}
2017-08-16 06:43:41 +00:00
}
var isFirstRun = ! File . Exists ( plugin . ConfigurationFilePath ) ;
plugin . SetStartupInfo ( isFirstRun , File . GetLastWriteTimeUtc , s = > Directory . CreateDirectory ( s ) ) ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error loading plugin {0}" , ex , plugin . GetType ( ) . FullName ) ;
return null ;
}
return plugin ;
}
/// <summary>
/// Discovers the types.
/// </summary>
protected void DiscoverTypes ( )
{
FailedAssemblies . Clear ( ) ;
var assemblies = GetComposablePartAssemblies ( ) . ToList ( ) ;
foreach ( var assembly in assemblies )
{
Logger . Info ( "Loading {0}" , assembly . FullName ) ;
}
AllConcreteTypes = assemblies
. SelectMany ( GetTypes )
. Where ( t = > t . IsClass & & ! t . IsAbstract & & ! t . IsInterface & & ! t . IsGenericType )
. ToArray ( ) ;
}
/// <summary>
/// Gets a list of types within an assembly
/// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference
/// </summary>
/// <param name="assembly">The assembly.</param>
/// <returns>IEnumerable{Type}.</returns>
/// <exception cref="System.ArgumentNullException">assembly</exception>
protected List < Type > GetTypes ( Assembly assembly )
{
if ( assembly = = null )
{
return new List < Type > ( ) ;
}
try
{
// This null checking really shouldn't be needed but adding it due to some
// unhandled exceptions in mono 5.0 that are a little hard to hunt down
var types = assembly . GetTypes ( ) ? ? new Type [ ] { } ;
return types . Where ( t = > t ! = null ) . ToList ( ) ;
}
catch ( ReflectionTypeLoadException ex )
{
if ( ex . LoaderExceptions ! = null )
{
foreach ( var loaderException in ex . LoaderExceptions )
{
if ( loaderException ! = null )
{
Logger . Error ( "LoaderException: " + loaderException . Message ) ;
}
}
}
// If it fails we can still get a list of the Types it was able to resolve
var types = ex . Types ? ? new Type [ ] { } ;
return types . Where ( t = > t ! = null ) . ToList ( ) ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error loading types from assembly" , ex ) ;
return new List < Type > ( ) ;
}
}
2017-05-01 02:22:13 +00:00
private CertificateInfo CertificateInfo { get ; set ; }
2017-09-03 02:42:13 +00:00
private X509Certificate Certificate { get ; set ; }
2015-01-19 06:42:31 +00:00
2015-01-19 04:29:57 +00:00
private IEnumerable < string > GetUrlPrefixes ( )
{
2016-08-18 06:26:47 +00:00
var hosts = new List < string > ( ) ;
2016-06-07 16:21:46 +00:00
2016-08-18 06:26:47 +00:00
hosts . Add ( "+" ) ;
2015-01-19 04:29:57 +00:00
2016-06-07 16:21:46 +00:00
return hosts . SelectMany ( i = >
{
var prefixes = new List < string >
{
2016-09-21 18:28:33 +00:00
"http://" + i + ":" + HttpPort + "/"
2016-06-07 16:21:46 +00:00
} ;
2017-05-01 02:22:13 +00:00
if ( CertificateInfo ! = null )
2016-06-07 16:21:46 +00:00
{
2016-09-21 18:28:33 +00:00
prefixes . Add ( "https://" + i + ":" + HttpsPort + "/" ) ;
2016-06-07 16:21:46 +00:00
}
return prefixes ;
} ) ;
2015-01-19 04:29:57 +00:00
}
2013-05-07 18:49:42 +00:00
/// <summary>
/// Starts the server.
/// </summary>
2014-12-27 22:52:41 +00:00
private void StartServer ( )
2015-01-19 07:12:01 +00:00
{
2016-09-21 17:07:18 +00:00
try
{
2017-08-30 18:52:29 +00:00
ServerManager . Start ( GetUrlPrefixes ( ) . ToArray ( ) ) ;
2016-09-21 17:07:18 +00:00
return ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error starting http server" , ex ) ;
2016-11-09 04:58:58 +00:00
if ( HttpPort = = ServerConfiguration . DefaultHttpPort )
2016-09-21 17:07:18 +00:00
{
throw ;
}
}
2016-11-09 04:58:58 +00:00
HttpPort = ServerConfiguration . DefaultHttpPort ;
2016-09-21 17:07:18 +00:00
2015-01-19 07:12:01 +00:00
try
{
2017-08-30 18:52:29 +00:00
ServerManager . Start ( GetUrlPrefixes ( ) . ToArray ( ) ) ;
2015-01-19 07:12:01 +00:00
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error starting http server" , ex ) ;
throw ;
}
}
2017-05-01 02:22:13 +00:00
private CertificateInfo GetCertificateInfo ( bool generateCertificate )
2013-05-07 18:49:42 +00:00
{
2015-01-23 06:15:15 +00:00
if ( ! string . IsNullOrWhiteSpace ( ServerConfigurationManager . Configuration . CertificatePath ) )
2013-05-07 18:49:42 +00:00
{
2015-01-23 06:15:15 +00:00
// Custom cert
2017-05-01 02:22:13 +00:00
return new CertificateInfo
{
2017-05-09 18:51:26 +00:00
Path = ServerConfigurationManager . Configuration . CertificatePath ,
Password = ServerConfigurationManager . Configuration . CertificatePassword
2017-05-01 02:22:13 +00:00
} ;
2015-01-23 06:15:15 +00:00
}
// Generate self-signed cert
var certHost = GetHostnameFromExternalDns ( ServerConfigurationManager . Configuration . WanDdns ) ;
2017-05-01 20:03:27 +00:00
var certPath = Path . Combine ( ServerConfigurationManager . ApplicationPaths . ProgramDataPath , "ssl" , "cert_" + ( certHost + "2" ) . GetMD5 ( ) . ToString ( "N" ) + ".pfx" ) ;
2017-05-01 02:22:13 +00:00
var password = "embycert" ;
2015-01-19 06:42:31 +00:00
2015-01-23 06:15:15 +00:00
if ( generateCertificate )
{
2015-09-13 21:32:02 +00:00
if ( ! FileSystemManager . FileExists ( certPath ) )
2015-01-18 21:44:35 +00:00
{
2017-05-04 18:14:45 +00:00
FileSystemManager . CreateDirectory ( FileSystemManager . GetDirectoryName ( certPath ) ) ;
2015-01-23 06:15:15 +00:00
try
2015-01-19 06:42:31 +00:00
{
2017-08-17 20:19:02 +00:00
CertificateGenerator . CreateSelfSignCertificatePfx ( certPath , certHost , password , Logger ) ;
2015-01-23 06:15:15 +00:00
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error creating ssl cert" , ex ) ;
return null ;
2015-01-19 06:42:31 +00:00
}
2015-01-18 21:44:35 +00:00
}
2013-05-07 18:49:42 +00:00
}
2013-10-18 16:09:47 +00:00
2017-05-01 02:22:13 +00:00
return new CertificateInfo
{
Path = certPath ,
Password = password
} ;
2013-05-07 18:49:42 +00:00
}
2013-05-07 19:07:51 +00:00
/// <summary>
/// Called when [configuration updated].
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
2017-08-16 06:43:41 +00:00
protected void OnConfigurationUpdated ( object sender , EventArgs e )
2013-05-07 19:07:51 +00:00
{
2017-08-16 06:43:41 +00:00
ConfigureAutorun ( ) ;
2013-05-07 19:07:51 +00:00
2015-01-19 04:29:57 +00:00
var requiresRestart = false ;
// Don't do anything if these haven't been set yet
if ( HttpPort ! = 0 & & HttpsPort ! = 0 )
{
// Need to restart if ports have changed
if ( ServerConfigurationManager . Configuration . HttpServerPortNumber ! = HttpPort | |
ServerConfigurationManager . Configuration . HttpsPortNumber ! = HttpsPort )
{
2015-02-11 04:05:58 +00:00
if ( ServerConfigurationManager . Configuration . IsPortAuthorized )
{
ServerConfigurationManager . Configuration . IsPortAuthorized = false ;
ServerConfigurationManager . SaveConfiguration ( ) ;
2015-01-19 04:29:57 +00:00
2015-02-11 04:05:58 +00:00
requiresRestart = true ;
}
2015-01-19 04:29:57 +00:00
}
}
if ( ! HttpServer . UrlPrefixes . SequenceEqual ( GetUrlPrefixes ( ) , StringComparer . OrdinalIgnoreCase ) )
2013-05-07 19:07:51 +00:00
{
2015-01-19 04:29:57 +00:00
requiresRestart = true ;
}
2015-01-04 05:55:34 +00:00
2017-05-01 02:22:13 +00:00
var currentCertPath = CertificateInfo = = null ? null : CertificateInfo . Path ;
var newCertInfo = GetCertificateInfo ( false ) ;
var newCertPath = newCertInfo = = null ? null : newCertInfo . Path ;
if ( ! string . Equals ( currentCertPath , newCertPath , StringComparison . OrdinalIgnoreCase ) )
2015-01-19 06:42:31 +00:00
{
requiresRestart = true ;
}
2015-01-19 04:29:57 +00:00
if ( requiresRestart )
{
2016-12-26 17:38:12 +00:00
Logger . Info ( "App needs to be restarted due to configuration change." ) ;
2013-05-07 19:07:51 +00:00
NotifyPendingRestart ( ) ;
}
}
2017-08-16 06:43:41 +00:00
/// <summary>
/// Notifies that the kernel that a change has been made that requires a restart
/// </summary>
public void NotifyPendingRestart ( )
{
Logger . Info ( "App needs to be restarted." ) ;
var changed = ! HasPendingRestart ;
HasPendingRestart = true ;
if ( changed )
{
EventHelper . QueueEventIfNotNull ( HasPendingRestartChanged , this , EventArgs . Empty , Logger ) ;
}
}
2013-02-24 21:53:54 +00:00
/// <summary>
/// Restarts this instance.
/// </summary>
2017-09-09 18:51:24 +00:00
public void Restart ( )
2013-02-24 21:53:54 +00:00
{
2013-10-07 14:38:31 +00:00
if ( ! CanSelfRestart )
{
2016-08-31 19:17:11 +00:00
throw new PlatformNotSupportedException ( "The server is unable to self-restart. Please restart manually." ) ;
2013-10-07 14:38:31 +00:00
}
2017-09-09 18:51:24 +00:00
if ( IsShuttingDown )
2013-09-05 17:26:03 +00:00
{
2017-09-09 18:51:24 +00:00
return ;
2013-09-05 17:26:03 +00:00
}
2017-09-09 18:51:24 +00:00
IsShuttingDown = true ;
Task . Run ( async ( ) = >
2013-09-05 17:26:03 +00:00
{
2017-09-09 18:51:24 +00:00
try
{
await SessionManager . SendServerRestartNotification ( CancellationToken . None ) . ConfigureAwait ( false ) ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error sending server restart notification" , ex ) ;
}
2013-09-05 17:26:03 +00:00
2017-09-09 18:51:24 +00:00
Logger . Info ( "Calling RestartInternal" ) ;
2014-06-04 16:15:44 +00:00
2017-09-09 18:51:24 +00:00
RestartInternal ( ) ;
} ) ;
2013-02-24 21:53:54 +00:00
}
2016-11-13 04:33:51 +00:00
protected abstract void RestartInternal ( ) ;
2013-02-24 21:53:54 +00:00
/// <summary>
/// Gets the composable part assemblies.
/// </summary>
/// <returns>IEnumerable{Assembly}.</returns>
2017-08-16 06:43:41 +00:00
protected IEnumerable < Assembly > GetComposablePartAssemblies ( )
2013-02-24 21:53:54 +00:00
{
2013-12-29 14:12:29 +00:00
var list = GetPluginAssemblies ( )
2013-09-25 00:54:51 +00:00
. ToList ( ) ;
2013-09-26 21:20:26 +00:00
2013-02-24 21:53:54 +00:00
// Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that
// This will prevent the .dll file from getting locked, and allow us to replace it when needed
2013-02-28 19:32:41 +00:00
// Include composable parts in the Api assembly
2016-11-11 17:33:10 +00:00
list . Add ( GetAssembly ( typeof ( ApiEntryPoint ) ) ) ;
2013-02-24 21:53:54 +00:00
2013-02-28 19:32:41 +00:00
// Include composable parts in the Dashboard assembly
2016-11-11 17:33:10 +00:00
list . Add ( GetAssembly ( typeof ( DashboardService ) ) ) ;
2013-02-24 21:53:54 +00:00
// Include composable parts in the Model assembly
2016-11-11 17:33:10 +00:00
list . Add ( GetAssembly ( typeof ( SystemInfo ) ) ) ;
2013-02-24 21:53:54 +00:00
// Include composable parts in the Common assembly
2016-11-11 17:33:10 +00:00
list . Add ( GetAssembly ( typeof ( IApplicationHost ) ) ) ;
2013-02-24 21:53:54 +00:00
// Include composable parts in the Controller assembly
2016-11-11 17:33:10 +00:00
list . Add ( GetAssembly ( typeof ( IServerApplicationHost ) ) ) ;
2013-02-24 21:53:54 +00:00
2013-06-09 16:47:28 +00:00
// Include composable parts in the Providers assembly
2016-11-11 17:33:10 +00:00
list . Add ( GetAssembly ( typeof ( ProviderUtils ) ) ) ;
2013-06-20 16:44:24 +00:00
2016-10-26 18:25:03 +00:00
// Include composable parts in the Photos assembly
2016-11-11 17:33:10 +00:00
list . Add ( GetAssembly ( typeof ( PhotoProvider ) ) ) ;
2016-10-26 18:25:03 +00:00
2016-11-02 20:53:50 +00:00
// Emby.Server implementations
2016-11-11 17:33:10 +00:00
list . Add ( GetAssembly ( typeof ( InstallationManager ) ) ) ;
2016-11-02 20:53:50 +00:00
2014-03-27 19:30:21 +00:00
// MediaEncoding
2017-08-09 19:56:38 +00:00
list . Add ( GetAssembly ( typeof ( MediaEncoding . Encoder . MediaEncoder ) ) ) ;
2014-03-27 19:30:21 +00:00
// Dlna
2016-11-11 17:33:10 +00:00
list . Add ( GetAssembly ( typeof ( DlnaEntryPoint ) ) ) ;
2014-02-28 04:49:02 +00:00
2014-06-30 03:04:50 +00:00
// Local metadata
2016-11-11 17:33:10 +00:00
list . Add ( GetAssembly ( typeof ( BoxSetXmlSaver ) ) ) ;
2014-06-30 03:04:50 +00:00
// Xbmc
2016-11-11 17:33:10 +00:00
list . Add ( GetAssembly ( typeof ( ArtistNfoProvider ) ) ) ;
2014-06-30 03:04:50 +00:00
2016-11-13 04:33:51 +00:00
list . AddRange ( GetAssembliesWithPartsInternal ( ) ) ;
2013-09-05 17:26:03 +00:00
2017-08-09 19:56:38 +00:00
return list . ToList ( ) ;
2013-02-24 21:53:54 +00:00
}
2013-02-26 16:10:55 +00:00
2016-11-13 04:33:51 +00:00
protected abstract List < Assembly > GetAssembliesWithPartsInternal ( ) ;
2013-12-29 14:12:29 +00:00
/// <summary>
/// Gets the plugin assemblies.
/// </summary>
/// <returns>IEnumerable{Assembly}.</returns>
private IEnumerable < Assembly > GetPluginAssemblies ( )
{
try
{
return Directory . EnumerateFiles ( ApplicationPaths . PluginsPath , "*.dll" , SearchOption . TopDirectoryOnly )
2016-10-28 03:16:38 +00:00
. Where ( EnablePlugin )
2013-12-29 14:12:29 +00:00
. Select ( LoadAssembly )
2013-12-29 17:07:29 +00:00
. Where ( a = > a ! = null )
. ToList ( ) ;
2013-12-29 14:12:29 +00:00
}
catch ( DirectoryNotFoundException )
{
return new List < Assembly > ( ) ;
}
}
2016-10-28 03:16:38 +00:00
private bool EnablePlugin ( string path )
{
var filename = Path . GetFileName ( path ) ;
var exclude = new [ ]
{
"mbplus.dll" ,
2016-12-26 17:38:12 +00:00
"mbintros.dll" ,
2017-09-07 18:17:18 +00:00
"embytv.dll" ,
"Messenger.dll" ,
"MediaBrowser.Plugins.TvMazeProvider.dll"
2016-10-28 03:16:38 +00:00
} ;
return ! exclude . Contains ( filename ? ? string . Empty , StringComparer . OrdinalIgnoreCase ) ;
}
2013-03-07 05:34:00 +00:00
/// <summary>
/// Gets the system status.
/// </summary>
/// <returns>SystemInfo.</returns>
2016-06-19 16:53:43 +00:00
public async Task < SystemInfo > GetSystemInfo ( )
2013-03-07 05:34:00 +00:00
{
2016-06-19 16:53:43 +00:00
var localAddress = await GetLocalApiUrl ( ) . ConfigureAwait ( false ) ;
2013-03-07 05:34:00 +00:00
return new SystemInfo
{
HasPendingRestart = HasPendingRestart ,
2017-09-09 18:51:24 +00:00
IsShuttingDown = IsShuttingDown ,
2013-03-07 05:34:00 +00:00
Version = ApplicationVersion . ToString ( ) ,
2015-01-19 04:29:57 +00:00
WebSocketPortNumber = HttpPort ,
2017-08-19 19:43:35 +00:00
FailedPluginAssemblies = FailedAssemblies . ToArray ( ) ,
InProgressInstallations = InstallationManager . CurrentInstallations . Select ( i = > i . Item1 ) . ToArray ( ) ,
CompletedInstallations = InstallationManager . CompletedInstallations . ToArray ( ) ,
2014-09-06 17:46:09 +00:00
Id = SystemId ,
2013-08-16 14:18:09 +00:00
ProgramDataPath = ApplicationPaths . ProgramDataPath ,
2013-11-30 18:32:39 +00:00
LogPath = ApplicationPaths . LogDirectoryPath ,
ItemsByNamePath = ApplicationPaths . ItemsByNamePath ,
2014-03-31 21:04:22 +00:00
InternalMetadataPath = ApplicationPaths . InternalMetadataPath ,
2013-12-15 01:17:57 +00:00
CachePath = ApplicationPaths . CachePath ,
2013-09-07 15:58:47 +00:00
MacAddress = GetMacAddress ( ) ,
2015-01-19 04:29:57 +00:00
HttpServerPortNumber = HttpPort ,
2015-01-19 21:08:58 +00:00
SupportsHttps = SupportsHttps ,
2015-01-19 04:29:57 +00:00
HttpsPortNumber = HttpsPort ,
2016-11-11 08:13:11 +00:00
OperatingSystem = EnvironmentInfo . OperatingSystem . ToString ( ) ,
2015-07-27 16:21:18 +00:00
OperatingSystemDisplayName = OperatingSystemDisplayName ,
2013-10-07 16:22:19 +00:00
CanSelfRestart = CanSelfRestart ,
2013-12-08 19:39:39 +00:00
CanSelfUpdate = CanSelfUpdate ,
2014-08-25 03:54:45 +00:00
WanAddress = ConnectManager . WanApiAddress ,
2014-04-26 02:55:07 +00:00
HasUpdateAvailable = HasUpdateAvailable ,
2014-01-18 19:25:20 +00:00
SupportsAutoRunAtStartup = SupportsAutoRunAtStartup ,
2014-01-30 00:18:05 +00:00
TranscodingTempPath = ApplicationPaths . TranscodingTempPath ,
2014-08-19 22:28:35 +00:00
ServerName = FriendlyName ,
2016-06-19 16:53:43 +00:00
LocalAddress = localAddress ,
2016-11-11 08:13:11 +00:00
SupportsLibraryMonitor = true ,
2016-06-29 05:49:31 +00:00
EncoderLocationType = MediaEncoder . EncoderLocationType ,
2016-11-11 08:13:11 +00:00
SystemArchitecture = EnvironmentInfo . SystemArchitecture ,
2017-04-10 01:51:36 +00:00
SystemUpdateLevel = SystemUpdateLevel ,
2016-11-13 04:33:51 +00:00
PackageName = StartupOptions . GetOption ( "-package" )
2013-03-07 05:34:00 +00:00
} ;
}
2015-01-19 04:29:57 +00:00
public bool EnableHttps
{
get
{
return SupportsHttps & & ServerConfigurationManager . Configuration . EnableHttps ;
}
}
public bool SupportsHttps
{
2016-11-11 03:29:51 +00:00
get { return Certificate ! = null ; }
2015-01-19 04:29:57 +00:00
}
2016-06-19 06:18:29 +00:00
public async Task < string > GetLocalApiUrl ( )
2014-08-19 22:28:35 +00:00
{
2016-06-19 06:18:29 +00:00
try
2014-08-19 22:28:35 +00:00
{
2016-06-19 06:18:29 +00:00
// Return the first matched address, if found, or the first known local address
2016-11-08 18:44:23 +00:00
var address = ( await GetLocalIpAddresses ( ) . ConfigureAwait ( false ) ) . FirstOrDefault ( i = > ! i . Equals ( IpAddressInfo . Loopback ) & & ! i . Equals ( IpAddressInfo . IPv6Loopback ) ) ;
2015-01-24 19:03:55 +00:00
2016-06-19 06:18:29 +00:00
if ( address ! = null )
2015-01-24 19:03:55 +00:00
{
2016-06-19 06:18:29 +00:00
return GetLocalApiUrl ( address ) ;
2015-01-24 19:03:55 +00:00
}
2015-08-10 17:37:50 +00:00
return null ;
2014-08-19 22:28:35 +00:00
}
2016-06-19 06:18:29 +00:00
catch ( Exception ex )
{
Logger . ErrorException ( "Error getting local Ip address information" , ex ) ;
}
return null ;
2015-01-24 19:03:55 +00:00
}
2014-08-19 22:28:35 +00:00
2016-11-08 18:44:23 +00:00
public string GetLocalApiUrl ( IpAddressInfo ipAddress )
2016-10-26 01:57:58 +00:00
{
2016-11-08 18:44:23 +00:00
if ( ipAddress . AddressFamily = = IpAddressFamily . InterNetworkV6 )
2016-03-09 17:40:29 +00:00
{
2016-11-08 18:44:23 +00:00
return GetLocalApiUrl ( "[" + ipAddress . Address + "]" ) ;
2016-03-09 17:40:29 +00:00
}
2016-11-08 18:44:23 +00:00
return GetLocalApiUrl ( ipAddress . Address ) ;
2016-03-09 17:40:29 +00:00
}
2015-02-10 05:54:58 +00:00
public string GetLocalApiUrl ( string host )
{
return string . Format ( "http://{0}:{1}" ,
host ,
HttpPort . ToString ( CultureInfo . InvariantCulture ) ) ;
}
2016-10-26 01:57:58 +00:00
public async Task < List < IpAddressInfo > > GetLocalIpAddresses ( )
{
2016-12-07 20:02:34 +00:00
var addresses = ServerConfigurationManager
. Configuration
. LocalNetworkAddresses
. Select ( NormalizeConfiguredLocalAddress )
. Where ( i = > i ! = null )
. ToList ( ) ;
2015-12-29 03:39:38 +00:00
2016-12-07 20:02:34 +00:00
if ( addresses . Count = = 0 )
2016-09-12 19:38:38 +00:00
{
2016-12-07 20:02:34 +00:00
addresses . AddRange ( NetworkManager . GetLocalIpAddresses ( ) ) ;
var list = new List < IpAddressInfo > ( ) ;
foreach ( var address in addresses )
2016-09-12 19:38:38 +00:00
{
2016-12-07 20:02:34 +00:00
var valid = await IsIpAddressValidAsync ( address ) . ConfigureAwait ( false ) ;
if ( valid )
{
list . Add ( address ) ;
}
2016-09-12 19:38:38 +00:00
}
2016-12-07 20:02:34 +00:00
addresses = list ;
2016-09-12 19:38:38 +00:00
}
2016-12-07 20:02:34 +00:00
return addresses ;
}
private IpAddressInfo NormalizeConfiguredLocalAddress ( string address )
{
var index = address . Trim ( '/' ) . IndexOf ( '/' ) ;
if ( index ! = - 1 )
{
address = address . Substring ( index + 1 ) ;
}
IpAddressInfo result ;
if ( NetworkManager . TryParseIpAddress ( address . Trim ( '/' ) , out result ) )
{
return result ;
}
return null ;
2014-08-19 22:28:35 +00:00
}
2015-12-29 03:39:38 +00:00
private readonly ConcurrentDictionary < string , bool > _validAddressResults = new ConcurrentDictionary < string , bool > ( StringComparer . OrdinalIgnoreCase ) ;
2016-01-28 06:38:35 +00:00
private DateTime _lastAddressCacheClear ;
2016-11-08 18:44:23 +00:00
private async Task < bool > IsIpAddressValidAsync ( IpAddressInfo address )
2014-09-17 03:04:10 +00:00
{
2016-11-08 18:44:23 +00:00
if ( address . Equals ( IpAddressInfo . Loopback ) | |
address . Equals ( IpAddressInfo . IPv6Loopback ) )
2014-09-17 03:04:10 +00:00
{
2015-12-29 03:39:38 +00:00
return true ;
}
2014-09-17 03:04:10 +00:00
2016-03-09 17:40:29 +00:00
var apiUrl = GetLocalApiUrl ( address ) ;
2015-12-29 03:39:38 +00:00
apiUrl + = "/system/ping" ;
2014-09-17 03:04:10 +00:00
2016-10-25 19:02:04 +00:00
if ( ( DateTime . UtcNow - _lastAddressCacheClear ) . TotalMinutes > = 15 )
2016-01-28 06:38:35 +00:00
{
_lastAddressCacheClear = DateTime . UtcNow ;
_validAddressResults . Clear ( ) ;
}
2015-12-29 03:39:38 +00:00
bool cachedResult ;
if ( _validAddressResults . TryGetValue ( apiUrl , out cachedResult ) )
{
return cachedResult ;
}
2014-09-17 03:04:10 +00:00
2015-12-29 03:39:38 +00:00
try
{
2016-01-28 06:38:35 +00:00
using ( var response = await HttpClient . SendAsync ( new HttpRequestOptions
2014-09-17 03:04:10 +00:00
{
2015-12-29 03:39:38 +00:00
Url = apiUrl ,
LogErrorResponseBody = false ,
2015-12-29 19:06:32 +00:00
LogErrors = false ,
2016-01-28 06:38:35 +00:00
LogRequest = false ,
2016-10-06 18:55:01 +00:00
TimeoutMs = 30000 ,
BufferContent = false
2014-09-17 03:04:10 +00:00
2016-01-28 06:38:35 +00:00
} , "POST" ) . ConfigureAwait ( false ) )
2015-12-29 03:39:38 +00:00
{
2015-12-29 19:06:32 +00:00
using ( var reader = new StreamReader ( response . Content ) )
{
var result = reader . ReadToEnd ( ) ;
var valid = string . Equals ( Name , result , StringComparison . OrdinalIgnoreCase ) ;
_validAddressResults . AddOrUpdate ( apiUrl , valid , ( k , v ) = > valid ) ;
2016-01-28 06:38:35 +00:00
//Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, valid);
2015-12-29 19:06:32 +00:00
return valid ;
}
2015-12-29 03:39:38 +00:00
}
2014-09-17 03:04:10 +00:00
}
2015-12-29 03:39:38 +00:00
catch
{
2016-01-28 06:38:35 +00:00
//Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false);
2015-12-29 19:06:32 +00:00
_validAddressResults . AddOrUpdate ( apiUrl , false , ( k , v ) = > false ) ;
2015-12-29 03:39:38 +00:00
return false ;
}
}
2014-08-05 23:59:24 +00:00
public string FriendlyName
{
get
{
return string . IsNullOrWhiteSpace ( ServerConfigurationManager . Configuration . ServerName )
? Environment . MachineName
: ServerConfigurationManager . Configuration . ServerName ;
}
}
2015-01-19 04:29:57 +00:00
public int HttpPort { get ; private set ; }
2014-03-17 04:25:11 +00:00
2015-01-19 04:29:57 +00:00
public int HttpsPort { get ; private set ; }
2015-01-07 03:36:42 +00:00
2013-08-16 14:18:09 +00:00
/// <summary>
/// Gets the mac address.
/// </summary>
/// <returns>System.String.</returns>
private string GetMacAddress ( )
{
try
{
return NetworkManager . GetMacAddress ( ) ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error getting mac address" , ex ) ;
return null ;
}
}
2013-02-26 16:10:55 +00:00
/// <summary>
/// Shuts down.
/// </summary>
2017-08-16 06:43:41 +00:00
public async Task Shutdown ( )
2013-02-26 16:10:55 +00:00
{
2017-09-09 18:51:24 +00:00
if ( IsShuttingDown )
{
return ;
}
IsShuttingDown = true ;
2013-09-05 17:26:03 +00:00
try
{
2013-10-03 18:02:23 +00:00
await SessionManager . SendServerShutdownNotification ( CancellationToken . None ) . ConfigureAwait ( false ) ;
2013-09-05 17:26:03 +00:00
}
catch ( Exception ex )
{
2013-10-03 18:02:23 +00:00
Logger . ErrorException ( "Error sending server shutdown notification" , ex ) ;
2013-09-05 17:26:03 +00:00
}
2016-11-13 04:33:51 +00:00
ShutdownInternal ( ) ;
2013-04-05 19:34:33 +00:00
}
2016-11-13 04:33:51 +00:00
protected abstract void ShutdownInternal ( ) ;
2013-03-27 22:13:46 +00:00
/// <summary>
/// Registers the server with administrator access.
/// </summary>
private void RegisterServerWithAdministratorAccess ( )
{
Logger . Info ( "Requesting administrative access to authorize http server" ) ;
2013-09-25 00:54:51 +00:00
try
2013-03-27 22:13:46 +00:00
{
2016-11-13 21:04:21 +00:00
AuthorizeServer ( ) ;
2017-01-17 18:00:19 +00:00
}
catch ( NotImplementedException )
{
2017-04-10 01:51:36 +00:00
2013-03-27 22:13:46 +00:00
}
2013-09-25 00:54:51 +00:00
catch ( Exception ex )
2013-03-27 22:13:46 +00:00
{
2013-09-25 00:54:51 +00:00
Logger . ErrorException ( "Error authorizing server" , ex ) ;
2013-03-27 22:13:46 +00:00
}
2013-02-26 16:10:55 +00:00
}
2013-07-08 17:13:18 +00:00
2017-02-19 03:46:09 +00:00
protected virtual void AuthorizeServer ( )
{
throw new NotImplementedException ( ) ;
}
2016-11-13 04:33:51 +00:00
2014-04-26 02:55:07 +00:00
public event EventHandler HasUpdateAvailableChanged ;
2014-01-05 06:50:48 +00:00
private bool _hasUpdateAvailable ;
2014-04-26 02:55:07 +00:00
public bool HasUpdateAvailable
{
get { return _hasUpdateAvailable ; }
set
{
var fireEvent = value & & ! _hasUpdateAvailable ;
_hasUpdateAvailable = value ;
if ( fireEvent )
{
EventHelper . FireEventIfNotNull ( HasUpdateAvailableChanged , this , EventArgs . Empty , Logger ) ;
}
}
}
2017-08-16 06:43:41 +00:00
/// <summary>
/// Removes the plugin.
/// </summary>
/// <param name="plugin">The plugin.</param>
public void RemovePlugin ( IPlugin plugin )
{
var list = Plugins . ToList ( ) ;
list . Remove ( plugin ) ;
Plugins = list . ToArray ( ) ;
}
2017-08-17 20:19:02 +00:00
2013-09-14 01:56:03 +00:00
/// <summary>
/// Checks for update.
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param>
/// <returns>Task{CheckForUpdateResult}.</returns>
2017-08-16 06:43:41 +00:00
public async Task < CheckForUpdateResult > CheckForApplicationUpdate ( CancellationToken cancellationToken , IProgress < double > progress )
2013-07-08 17:13:18 +00:00
{
2017-09-09 18:51:24 +00:00
var cacheLength = TimeSpan . FromMinutes ( 5 ) ;
2017-04-10 01:51:36 +00:00
var updateLevel = SystemUpdateLevel ;
2016-01-03 01:23:09 +00:00
2017-09-09 18:51:24 +00:00
var result = await new GithubUpdater ( HttpClient , JsonSerializer ) . CheckForUpdateResult ( "MediaBrowser" ,
"Emby" ,
ApplicationVersion ,
updateLevel ,
ReleaseAssetFilename ,
"MBServer" ,
UpdateTargetFileName ,
cacheLength ,
cancellationToken ) . ConfigureAwait ( false ) ;
2016-01-09 17:17:35 +00:00
HasUpdateAvailable = result . IsUpdateAvailable ;
return result ;
2013-07-08 17:13:18 +00:00
}
2013-08-28 20:12:58 +00:00
2017-09-09 18:51:24 +00:00
protected virtual string UpdateTargetFileName
{
get { return "Mbserver.zip" ; }
}
2013-09-14 01:56:03 +00:00
/// <summary>
/// Updates the application.
/// </summary>
/// <param name="package">The package that contains the update</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param>
2017-08-16 06:43:41 +00:00
public async Task UpdateApplication ( PackageVersionInfo package , CancellationToken cancellationToken , IProgress < double > progress )
2013-09-14 01:56:03 +00:00
{
2016-01-03 01:23:09 +00:00
await InstallationManager . InstallPackage ( package , false , progress , cancellationToken ) . ConfigureAwait ( false ) ;
2013-09-14 01:56:03 +00:00
2014-04-26 02:55:07 +00:00
HasUpdateAvailable = false ;
2014-01-05 06:50:48 +00:00
2014-04-30 15:07:02 +00:00
OnApplicationUpdated ( package ) ;
2013-09-14 01:56:03 +00:00
}
2014-01-06 01:59:21 +00:00
/// <summary>
/// Configures the automatic run at startup.
/// </summary>
/// <param name="autorun">if set to <c>true</c> [autorun].</param>
2017-08-16 06:43:41 +00:00
protected void ConfigureAutoRunAtStartup ( bool autorun )
2013-09-25 00:54:51 +00:00
{
2014-01-06 01:59:21 +00:00
if ( SupportsAutoRunAtStartup )
{
2016-11-13 04:33:51 +00:00
ConfigureAutoRunInternal ( autorun ) ;
2014-01-06 01:59:21 +00:00
}
2013-08-28 20:12:58 +00:00
}
2015-01-18 21:44:35 +00:00
2017-02-19 03:46:09 +00:00
protected virtual void ConfigureAutoRunInternal ( bool autorun )
{
throw new NotImplementedException ( ) ;
}
2016-11-13 04:33:51 +00:00
2015-01-18 21:44:35 +00:00
/// <summary>
/// This returns localhost in the case of no external dns, and the hostname if the
/// dns is prefixed with a valid Uri prefix.
/// </summary>
/// <param name="externalDns">The external dns prefix to get the hostname of.</param>
/// <returns>The hostname in <paramref name="externalDns"/></returns>
private static string GetHostnameFromExternalDns ( string externalDns )
{
if ( string . IsNullOrWhiteSpace ( externalDns ) )
{
return "localhost" ;
}
try
{
2015-01-19 06:42:31 +00:00
return new Uri ( externalDns ) . Host ;
2015-01-18 21:44:35 +00:00
}
2016-08-05 21:15:48 +00:00
catch
2015-01-18 21:44:35 +00:00
{
return externalDns ;
}
}
2016-04-24 03:03:49 +00:00
2016-11-20 23:48:52 +00:00
public void LaunchUrl ( string url )
{
2016-12-22 04:11:23 +00:00
if ( EnvironmentInfo . OperatingSystem ! = MediaBrowser . Model . System . OperatingSystem . Windows & &
EnvironmentInfo . OperatingSystem ! = MediaBrowser . Model . System . OperatingSystem . OSX )
2016-11-20 23:48:52 +00:00
{
throw new NotImplementedException ( ) ;
}
2016-12-07 20:02:34 +00:00
var process = ProcessFactory . Create ( new ProcessOptions
{
2016-11-20 23:48:52 +00:00
FileName = url ,
2016-12-22 04:28:00 +00:00
//EnableRaisingEvents = true,
2016-11-20 23:48:52 +00:00
UseShellExecute = true ,
ErrorDialog = false
} ) ;
process . Exited + = ProcessExited ;
try
{
process . Start ( ) ;
}
catch ( Exception ex )
{
Console . WriteLine ( "Error launching url: {0}" , url ) ;
Logger . ErrorException ( "Error launching url: {0}" , ex , url ) ;
throw ;
}
}
private static void ProcessExited ( object sender , EventArgs e )
{
( ( IProcess ) sender ) . Dispose ( ) ;
}
2016-09-03 17:16:36 +00:00
2017-03-22 18:37:04 +00:00
public virtual void EnableLoopback ( string appName )
2016-09-03 17:16:36 +00:00
{
2017-02-19 03:46:09 +00:00
}
2016-11-13 04:33:51 +00:00
2016-10-29 04:10:11 +00:00
private void RegisterModules ( )
{
var moduleTypes = GetExportTypes < IDependencyModule > ( ) ;
foreach ( var type in moduleTypes )
{
try
{
var instance = Activator . CreateInstance ( type ) as IDependencyModule ;
if ( instance ! = null )
instance . BindDependencies ( this ) ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error setting up dependency bindings for " + type . Name , ex ) ;
}
}
}
2017-08-16 06:43:41 +00:00
/// <summary>
/// Called when [application updated].
/// </summary>
/// <param name="package">The package.</param>
protected void OnApplicationUpdated ( PackageVersionInfo package )
{
Logger . Info ( "Application has been updated to version {0}" , package . versionStr ) ;
EventHelper . FireEventIfNotNull ( ApplicationUpdated , this , new GenericEventArgs < PackageVersionInfo >
{
Argument = package
} , Logger ) ;
NotifyPendingRestart ( ) ;
}
2017-08-17 20:19:02 +00:00
private bool _disposed ;
2017-08-16 06:43:41 +00:00
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose ( )
{
2017-08-17 20:19:02 +00:00
if ( ! _disposed )
{
_disposed = true ;
Dispose ( true ) ;
2017-09-05 19:49:02 +00:00
GC . SuppressFinalize ( this ) ;
2017-08-17 20:19:02 +00:00
}
2017-08-16 06:43:41 +00:00
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose ( bool dispose )
{
if ( dispose )
{
var type = GetType ( ) ;
2017-09-05 19:49:02 +00:00
LogManager . AddConsoleOutput ( ) ;
2017-08-16 06:43:41 +00:00
Logger . Info ( "Disposing " + type . Name ) ;
var parts = DisposableParts . Distinct ( ) . Where ( i = > i . GetType ( ) ! = type ) . ToList ( ) ;
DisposableParts . Clear ( ) ;
foreach ( var part in parts )
{
Logger . Info ( "Disposing " + part . GetType ( ) . Name ) ;
try
{
part . Dispose ( ) ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error disposing {0}" , ex , part . GetType ( ) . Name ) ;
}
}
}
}
2016-10-29 04:10:11 +00:00
void IDependencyContainer . RegisterSingleInstance < T > ( T obj , bool manageLifetime )
{
RegisterSingleInstance ( obj , manageLifetime ) ;
}
void IDependencyContainer . RegisterSingleInstance < T > ( Func < T > func )
{
RegisterSingleInstance ( func ) ;
}
void IDependencyContainer . Register ( Type typeInterface , Type typeImplementation )
{
Container . Register ( typeInterface , typeImplementation ) ;
}
2017-05-01 02:22:13 +00:00
}
2016-10-29 04:10:11 +00:00
2017-05-01 02:22:13 +00:00
internal class CertificateInfo
{
public string Path { get ; set ; }
public string Password { get ; set ; }
2013-02-24 21:53:54 +00:00
}
}