Forráskód Böngészése

update .net core startup

Luke Pulverenti 8 éve
szülő
commit
0e9cd51f9c
38 módosított fájl, 353 hozzáadás és 323 törlés
  1. 2 2
      Emby.Common.Implementations/BaseApplicationHost.cs
  2. 3 7
      Emby.Common.Implementations/BaseApplicationPaths.cs
  3. 10 0
      Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs
  4. 8 0
      Emby.Common.Implementations/IO/ManagedFileSystem.cs
  5. 9 0
      Emby.Common.Implementations/Net/NetSocket.cs
  6. 19 5
      Emby.Common.Implementations/Net/SocketAcceptor.cs
  7. 6 1
      Emby.Common.Implementations/Net/SocketFactory.cs
  8. 7 7
      Emby.Server.Core/ApplicationHost.cs
  9. 2 2
      Emby.Server.Core/Data/DataExtensions.cs
  10. 16 3
      Emby.Server.Core/Data/SqliteItemRepository.cs
  11. 1 1
      Emby.Server.Core/Notifications/SqliteNotificationsRepository.cs
  12. 2 2
      Emby.Server.Core/ServerApplicationPaths.cs
  13. 14 2
      Emby.Server.Implementations/Channels/ChannelManager.cs
  14. 2 0
      Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
  15. 71 19
      Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
  16. 1 2
      Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs
  17. 16 4
      Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs
  18. 50 17
      Emby.Server.Implementations/LiveTv/LiveTvManager.cs
  19. 13 1
      Emby.Server.Implementations/LiveTv/ProgramImageProvider.cs
  20. 5 1
      MediaBrowser.Api/ApiEntryPoint.cs
  21. 0 6
      MediaBrowser.Common/Configuration/IApplicationPaths.cs
  22. 1 18
      MediaBrowser.Controller/Entities/BaseItem.cs
  23. 9 7
      MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
  24. 1 0
      MediaBrowser.Model/IO/IFileSystem.cs
  25. 2 0
      MediaBrowser.Model/System/IEnvironmentInfo.cs
  26. 1 1
      MediaBrowser.Server.Mono/MonoAppHost.cs
  27. 9 1
      MediaBrowser.Server.Mono/Program.cs
  28. 5 1
      MediaBrowser.Server.Startup.Common/Persistence/SqliteExtensions.cs
  29. 16 12
      MediaBrowser.ServerApplication/MainStartup.cs
  30. 1 1
      MediaBrowser.ServerApplication/Updates/ApplicationUpdater.cs
  31. 7 2
      MediaBrowser.ServerApplication/WindowsAppHost.cs
  32. 0 2
      MediaBrowser.XbmcMetadata/Savers/SeriesNfoSaver.cs
  33. 1 1
      Nuget/MediaBrowser.Common.nuspec
  34. 2 2
      Nuget/MediaBrowser.Server.Core.nuspec
  35. 2 9
      src/Emby.Server/ApplicationPathHelper.cs
  36. 1 1
      src/Emby.Server/CoreAppHost.cs
  37. 34 179
      src/Emby.Server/Program.cs
  38. 4 4
      src/Emby.Server/project.json

+ 2 - 2
Emby.Common.Implementations/BaseApplicationHost.cs

@@ -326,7 +326,7 @@ namespace Emby.Common.Implementations
 
 
             builder.AppendLine(string.Format("Processor count: {0}", Environment.ProcessorCount));
             builder.AppendLine(string.Format("Processor count: {0}", Environment.ProcessorCount));
             builder.AppendLine(string.Format("Program data path: {0}", appPaths.ProgramDataPath));
             builder.AppendLine(string.Format("Program data path: {0}", appPaths.ProgramDataPath));
-            builder.AppendLine(string.Format("Application Path: {0}", appPaths.ApplicationPath));
+            builder.AppendLine(string.Format("Application directory: {0}", appPaths.ProgramSystemPath));
 
 
             return builder;
             return builder;
         }
         }
@@ -548,7 +548,7 @@ return null;
             TimerFactory = new TimerFactory();
             TimerFactory = new TimerFactory();
             RegisterSingleInstance(TimerFactory);
             RegisterSingleInstance(TimerFactory);
 
 
-            SocketFactory = new SocketFactory(null);
+            SocketFactory = new SocketFactory(LogManager.GetLogger("SocketFactory"));
             RegisterSingleInstance(SocketFactory);
             RegisterSingleInstance(SocketFactory);
 
 
             RegisterSingleInstance(CryptographyProvider);
             RegisterSingleInstance(CryptographyProvider);

+ 3 - 7
Emby.Common.Implementations/BaseApplicationPaths.cs

@@ -12,22 +12,18 @@ namespace Emby.Common.Implementations
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="BaseApplicationPaths"/> class.
         /// Initializes a new instance of the <see cref="BaseApplicationPaths"/> class.
         /// </summary>
         /// </summary>
-        protected BaseApplicationPaths(string programDataPath, string applicationPath)
+        protected BaseApplicationPaths(string programDataPath, string appFolderPath)
         {
         {
             ProgramDataPath = programDataPath;
             ProgramDataPath = programDataPath;
-            ApplicationPath = applicationPath;
+            ProgramSystemPath = appFolderPath;
         }
         }
 
 
-        public string ApplicationPath { get; private set; }
         public string ProgramDataPath { get; private set; }
         public string ProgramDataPath { get; private set; }
 
 
         /// <summary>
         /// <summary>
         /// Gets the path to the system folder
         /// Gets the path to the system folder
         /// </summary>
         /// </summary>
-        public string ProgramSystemPath
-        {
-            get { return Path.GetDirectoryName(ApplicationPath); }
-        }
+        public string ProgramSystemPath { get; private set; }
 
 
         /// <summary>
         /// <summary>
         /// The _data directory
         /// The _data directory

+ 10 - 0
Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs

@@ -95,5 +95,15 @@ namespace Emby.Common.Implementations.EnvironmentInfo
                 return MediaBrowser.Model.System.Architecture.X64;
                 return MediaBrowser.Model.System.Architecture.X64;
             }
             }
         }
         }
+
+        public string GetEnvironmentVariable(string name)
+        {
+            return Environment.GetEnvironmentVariable(name);
+        }
+
+        public virtual string GetUserId()
+        {
+            return null;
+        }
     }
     }
 }
 }

+ 8 - 0
Emby.Common.Implementations/IO/ManagedFileSystem.cs

@@ -57,6 +57,14 @@ namespace Emby.Common.Implementations.IO
             }
             }
         }
         }
 
 
+        public char PathSeparator
+        {
+            get
+            {
+                return Path.DirectorySeparatorChar;
+            }
+        }
+
         public string GetFullPath(string path)
         public string GetFullPath(string path)
         {
         {
             return Path.GetFullPath(path);
             return Path.GetFullPath(path);

+ 9 - 0
Emby.Common.Implementations/Net/NetSocket.cs

@@ -15,6 +15,15 @@ namespace Emby.Common.Implementations.Net
 
 
         public NetSocket(Socket socket, ILogger logger)
         public NetSocket(Socket socket, ILogger logger)
         {
         {
+            if (socket == null)
+            {
+                throw new ArgumentNullException("socket");
+            }
+            if (logger == null)
+            {
+                throw new ArgumentNullException("logger");
+            }
+
             Socket = socket;
             Socket = socket;
             _logger = logger;
             _logger = logger;
         }
         }

+ 19 - 5
Emby.Common.Implementations/Net/SocketAcceptor.cs

@@ -14,6 +14,23 @@ namespace Emby.Common.Implementations.Net
 
 
         public SocketAcceptor(ILogger logger, Socket originalSocket, Action<ISocket> onAccept, Func<bool> isClosed)
         public SocketAcceptor(ILogger logger, Socket originalSocket, Action<ISocket> onAccept, Func<bool> isClosed)
         {
         {
+            if (logger == null)
+            {
+                throw new ArgumentNullException("logger");
+            }
+            if (originalSocket == null)
+            {
+                throw new ArgumentNullException("originalSocket");
+            }
+            if (onAccept == null)
+            {
+                throw new ArgumentNullException("onAccept");
+            }
+            if (isClosed == null)
+            {
+                throw new ArgumentNullException("isClosed");
+            }
+
             _logger = logger;
             _logger = logger;
             _originalSocket = originalSocket;
             _originalSocket = originalSocket;
             _isClosed = isClosed;
             _isClosed = isClosed;
@@ -101,11 +118,8 @@ namespace Emby.Common.Implementations.Net
                 _onAccept(new NetSocket(acceptSocket, _logger));
                 _onAccept(new NetSocket(acceptSocket, _logger));
             }
             }
 
 
-            if (_originalSocket != null)
-            {
-                // Accept the next connection request
-                StartAccept(e, ref acceptSocket);
-            }
+            // Accept the next connection request
+            StartAccept(e, ref acceptSocket);
         }
         }
     }
     }
 }
 }

+ 6 - 1
Emby.Common.Implementations/Net/SocketFactory.cs

@@ -23,10 +23,15 @@ namespace Emby.Common.Implementations.Net
         /// </summary>
         /// </summary>
         private IPAddress _LocalIP;
         private IPAddress _LocalIP;
 
 
-        private ILogger _logger;
+        private readonly ILogger _logger;
 
 
         public SocketFactory(ILogger logger)
         public SocketFactory(ILogger logger)
         {
         {
+            if (logger == null)
+            {
+                throw new ArgumentNullException("logger");
+            }
+
             _logger = logger;
             _logger = logger;
             _LocalIP = IPAddress.Any;
             _LocalIP = IPAddress.Any;
         }
         }

+ 7 - 7
Emby.Server.Core/ApplicationHost.cs

@@ -725,6 +725,11 @@ namespace Emby.Server.Core
 
 
             try
             try
             {
             {
+                if (!FileSystemManager.FileExists(certificateLocation))
+                {
+                    return null;
+                }
+
                 X509Certificate2 localCert = new X509Certificate2(certificateLocation);
                 X509Certificate2 localCert = new X509Certificate2(certificateLocation);
                 //localCert.PrivateKey = PrivateKey.CreateFromFile(pvk_file).RSA;
                 //localCert.PrivateKey = PrivateKey.CreateFromFile(pvk_file).RSA;
                 if (!localCert.HasPrivateKey)
                 if (!localCert.HasPrivateKey)
@@ -1438,12 +1443,7 @@ namespace Emby.Server.Core
 
 
             try
             try
             {
             {
-                AuthorizeServer(
-                    UdpServerEntryPoint.PortNumber,
-                    ServerConfigurationManager.Configuration.HttpServerPortNumber,
-                    ServerConfigurationManager.Configuration.HttpsPortNumber,
-                    ConfigurationManager.CommonApplicationPaths.ApplicationPath,
-                    ConfigurationManager.CommonApplicationPaths.TempDirectory);
+                AuthorizeServer();
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {
@@ -1451,7 +1451,7 @@ namespace Emby.Server.Core
             }
             }
         }
         }
 
 
-        protected abstract void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory);
+        protected abstract void AuthorizeServer();
         protected abstract IDbConnector GetDbConnector();
         protected abstract IDbConnector GetDbConnector();
 
 
         public event EventHandler HasUpdateAvailableChanged;
         public event EventHandler HasUpdateAvailableChanged;

+ 2 - 2
Emby.Server.Core/Data/DataExtensions.cs

@@ -40,7 +40,7 @@ namespace Emby.Server.Core.Data
         public static IDataParameter Add(this IDataParameterCollection paramCollection, IDbCommand cmd, string name)
         public static IDataParameter Add(this IDataParameterCollection paramCollection, IDbCommand cmd, string name)
         {
         {
             var param = cmd.CreateParameter();
             var param = cmd.CreateParameter();
-
+            
             param.ParameterName = name;
             param.ParameterName = name;
 
 
             paramCollection.Add(param);
             paramCollection.Add(param);
@@ -173,7 +173,7 @@ namespace Emby.Server.Core.Data
             var builder = new StringBuilder();
             var builder = new StringBuilder();
 
 
             builder.AppendLine("alter table " + table);
             builder.AppendLine("alter table " + table);
-            builder.AppendLine("add column " + columnName + " " + type);
+            builder.AppendLine("add column " + columnName + " " + type + " NULL");
 
 
             connection.RunQueries(new[] { builder.ToString() }, logger);
             connection.RunQueries(new[] { builder.ToString() }, logger);
         }
         }

+ 16 - 3
Emby.Server.Core/Data/SqliteItemRepository.cs

@@ -157,7 +157,7 @@ namespace Emby.Server.Core.Data
 
 
             string[] queries = {
             string[] queries = {
 
 
-                                "create table if not exists TypedBaseItems (guid GUID primary key, type TEXT, data BLOB, ParentId GUID, Path TEXT)",
+                                "create table if not exists TypedBaseItems (guid GUID primary key NOT NULL, type TEXT NOT NULL, data BLOB NULL, ParentId GUID NULL, Path TEXT NULL)",
 
 
                                 "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
                                 "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
                                 "create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
                                 "create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
@@ -286,6 +286,7 @@ namespace Emby.Server.Core.Data
             _connection.AddColumn(Logger, "TypedBaseItems", "ExtraType", "Text");
             _connection.AddColumn(Logger, "TypedBaseItems", "ExtraType", "Text");
             _connection.AddColumn(Logger, "TypedBaseItems", "Artists", "Text");
             _connection.AddColumn(Logger, "TypedBaseItems", "Artists", "Text");
             _connection.AddColumn(Logger, "TypedBaseItems", "AlbumArtists", "Text");
             _connection.AddColumn(Logger, "TypedBaseItems", "AlbumArtists", "Text");
+            _connection.AddColumn(Logger, "TypedBaseItems", "ExternalId", "Text");
 
 
             _connection.AddColumn(Logger, "ItemValues", "CleanValue", "Text");
             _connection.AddColumn(Logger, "ItemValues", "CleanValue", "Text");
 
 
@@ -440,7 +441,8 @@ namespace Emby.Server.Core.Data
             "TotalBitrate",
             "TotalBitrate",
             "ExtraType",
             "ExtraType",
             "Artists",
             "Artists",
-            "AlbumArtists"
+            "AlbumArtists",
+            "ExternalId"
         };
         };
 
 
         private readonly string[] _mediaStreamSaveColumns =
         private readonly string[] _mediaStreamSaveColumns =
@@ -575,7 +577,8 @@ namespace Emby.Server.Core.Data
                 "TotalBitrate",
                 "TotalBitrate",
                 "ExtraType",
                 "ExtraType",
                 "Artists",
                 "Artists",
-                "AlbumArtists"
+                "AlbumArtists",
+                "ExternalId"
             };
             };
             _saveItemCommand = _connection.CreateCommand();
             _saveItemCommand = _connection.CreateCommand();
             _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
             _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
@@ -1084,6 +1087,10 @@ namespace Emby.Server.Core.Data
                         }
                         }
                     }
                     }
 
 
+                    _saveItemCommand.GetParameter(index++).Value = item.ExternalId;
+
+                    //Logger.Debug(_saveItemCommand.CommandText);
+
                     _saveItemCommand.Transaction = transaction;
                     _saveItemCommand.Transaction = transaction;
 
 
                     _saveItemCommand.ExecuteNonQuery();
                     _saveItemCommand.ExecuteNonQuery();
@@ -1967,6 +1974,12 @@ namespace Emby.Server.Core.Data
             }
             }
             index++;
             index++;
 
 
+            if (!reader.IsDBNull(index))
+            {
+                item.ExternalId = reader.GetString(index);
+            }
+            index++;
+
             if (string.IsNullOrWhiteSpace(item.Tagline))
             if (string.IsNullOrWhiteSpace(item.Tagline))
             {
             {
                 var movie = item as Movie;
                 var movie = item as Movie;

+ 1 - 1
Emby.Server.Core/Notifications/SqliteNotificationsRepository.cs

@@ -30,7 +30,7 @@ namespace Emby.Server.Core.Notifications
             {
             {
                 string[] queries = {
                 string[] queries = {
 
 
-                                "create table if not exists Notifications (Id GUID NOT NULL, UserId GUID NOT NULL, Date DATETIME NOT NULL, Name TEXT NOT NULL, Description TEXT, Url TEXT, Level TEXT NOT NULL, IsRead BOOLEAN NOT NULL, Category TEXT NOT NULL, RelatedId TEXT, PRIMARY KEY (Id, UserId))",
+                                "create table if not exists Notifications (Id GUID NOT NULL, UserId GUID NOT NULL, Date DATETIME NOT NULL, Name TEXT NOT NULL, Description TEXT NULL, Url TEXT NULL, Level TEXT NOT NULL, IsRead BOOLEAN NOT NULL, Category TEXT NOT NULL, RelatedId TEXT NULL, PRIMARY KEY (Id, UserId))",
                                 "create index if not exists idx_Notifications1 on Notifications(Id)",
                                 "create index if not exists idx_Notifications1 on Notifications(Id)",
                                 "create index if not exists idx_Notifications2 on Notifications(UserId)"
                                 "create index if not exists idx_Notifications2 on Notifications(UserId)"
                                };
                                };

+ 2 - 2
Emby.Server.Core/ServerApplicationPaths.cs

@@ -12,8 +12,8 @@ namespace Emby.Server.Core
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="BaseApplicationPaths" /> class.
         /// Initializes a new instance of the <see cref="BaseApplicationPaths" /> class.
         /// </summary>
         /// </summary>
-        public ServerApplicationPaths(string programDataPath, string applicationPath, string applicationResourcesPath)
-            : base(programDataPath, applicationPath)
+        public ServerApplicationPaths(string programDataPath, string appFolderPath, string applicationResourcesPath)
+            : base(programDataPath, appFolderPath)
         {
         {
             ApplicationResourcesPath = applicationResourcesPath;
             ApplicationResourcesPath = applicationResourcesPath;
         }
         }

+ 14 - 2
Emby.Server.Implementations/Channels/ChannelManager.cs

@@ -326,7 +326,7 @@ namespace Emby.Server.Implementations.Channels
 
 
             if (requiresCallback != null)
             if (requiresCallback != null)
             {
             {
-                results = await GetChannelItemMediaSourcesInternal(requiresCallback, item.ExternalId, cancellationToken)
+                results = await GetChannelItemMediaSourcesInternal(requiresCallback, GetItemExternalId(item), cancellationToken)
                     .ConfigureAwait(false);
                     .ConfigureAwait(false);
             }
             }
             else
             else
@@ -1075,6 +1075,18 @@ namespace Emby.Server.Implementations.Channels
             return result;
             return result;
         }
         }
 
 
+        private string GetItemExternalId(BaseItem item)
+        {
+            var externalId = item.ExternalId;
+
+            if (string.IsNullOrWhiteSpace(externalId))
+            {
+                externalId = item.GetProviderId("ProviderExternalId");
+            }
+
+            return externalId;
+        }
+
         private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
         private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
         private async Task<ChannelItemResult> GetChannelItems(IChannel channel,
         private async Task<ChannelItemResult> GetChannelItems(IChannel channel,
             User user,
             User user,
@@ -1145,7 +1157,7 @@ namespace Emby.Server.Implementations.Channels
                 {
                 {
                     var categoryItem = _libraryManager.GetItemById(new Guid(folderId));
                     var categoryItem = _libraryManager.GetItemById(new Guid(folderId));
 
 
-                    query.FolderId = categoryItem.ExternalId;
+                    query.FolderId = GetItemExternalId(categoryItem);
                 }
                 }
 
 
                 var result = await channel.GetChannelItems(query, cancellationToken).ConfigureAwait(false);
                 var result = await channel.GetChannelItems(query, cancellationToken).ConfigureAwait(false);

+ 2 - 0
Emby.Server.Implementations/HttpServer/HttpListenerHost.cs

@@ -396,6 +396,8 @@ namespace Emby.Server.Implementations.HttpServer
                 if (_disposed)
                 if (_disposed)
                 {
                 {
                     httpRes.StatusCode = 503;
                     httpRes.StatusCode = 503;
+                    httpRes.ContentType = "text/plain";
+                    Write(httpRes, "Server shutting down");
                     return;
                     return;
                 }
                 }
 
 

+ 71 - 19
Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs

@@ -1551,13 +1551,28 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
         {
         {
             try
             try
             {
             {
+                if (timer.IsSports)
+                {
+                    AddGenre(timer.Genres, "Sports");
+                }
+                if (timer.IsKids)
+                {
+                    AddGenre(timer.Genres, "Kids");
+                    AddGenre(timer.Genres, "Children");
+                }
+                if (timer.IsNews)
+                {
+                    AddGenre(timer.Genres, "News");
+                }
+
                 if (timer.IsProgramSeries)
                 if (timer.IsProgramSeries)
                 {
                 {
                     SaveSeriesNfo(timer, recordingPath, seriesPath);
                     SaveSeriesNfo(timer, recordingPath, seriesPath);
+                    SaveVideoNfo(timer, recordingPath, false);
                 }
                 }
                 else if (!timer.IsMovie || timer.IsSports || timer.IsNews)
                 else if (!timer.IsMovie || timer.IsSports || timer.IsNews)
                 {
                 {
-                    SaveVideoNfo(timer, recordingPath);
+                    SaveVideoNfo(timer, recordingPath, true);
                 }
                 }
             }
             }
             catch (Exception ex)
             catch (Exception ex)
@@ -1594,6 +1609,16 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                         writer.WriteElementString("title", timer.Name);
                         writer.WriteElementString("title", timer.Name);
                     }
                     }
 
 
+                    if (!string.IsNullOrEmpty(timer.OfficialRating))
+                    {
+                        writer.WriteElementString("mpaa", timer.OfficialRating);
+                    }
+
+                    foreach (var genre in timer.Genres)
+                    {
+                        writer.WriteElementString("genre", genre);
+                    }
+
                     writer.WriteEndElement();
                     writer.WriteEndElement();
                     writer.WriteEndDocument();
                     writer.WriteEndDocument();
                 }
                 }
@@ -1601,7 +1626,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
         }
         }
 
 
         public const string DateAddedFormat = "yyyy-MM-dd HH:mm:ss";
         public const string DateAddedFormat = "yyyy-MM-dd HH:mm:ss";
-        private void SaveVideoNfo(TimerInfo timer, string recordingPath)
+        private void SaveVideoNfo(TimerInfo timer, string recordingPath, bool lockData)
         {
         {
             var nfoPath = Path.ChangeExtension(recordingPath, ".nfo");
             var nfoPath = Path.ChangeExtension(recordingPath, ".nfo");
 
 
@@ -1622,11 +1647,41 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                 using (XmlWriter writer = XmlWriter.Create(stream, settings))
                 using (XmlWriter writer = XmlWriter.Create(stream, settings))
                 {
                 {
                     writer.WriteStartDocument(true);
                     writer.WriteStartDocument(true);
-                    writer.WriteStartElement("movie");
 
 
-                    if (!string.IsNullOrWhiteSpace(timer.Name))
+                    if (timer.IsProgramSeries)
                     {
                     {
-                        writer.WriteElementString("title", timer.Name);
+                        writer.WriteStartElement("episodedetails");
+
+                        if (!string.IsNullOrWhiteSpace(timer.EpisodeTitle))
+                        {
+                            writer.WriteElementString("title", timer.EpisodeTitle);
+                        }
+
+                        if (timer.OriginalAirDate.HasValue)
+                        {
+                            var formatString = _config.GetNfoConfiguration().ReleaseDateFormat;
+
+                            writer.WriteElementString("aired", timer.OriginalAirDate.Value.ToLocalTime().ToString(formatString));
+                        }
+
+                        if (timer.EpisodeNumber.HasValue)
+                        {
+                            writer.WriteElementString("episode", timer.EpisodeNumber.Value.ToString(CultureInfo.InvariantCulture));
+                        }
+
+                        if (timer.SeasonNumber.HasValue)
+                        {
+                            writer.WriteElementString("season", timer.SeasonNumber.Value.ToString(CultureInfo.InvariantCulture));
+                        }
+                    }
+                    else
+                    {
+                        writer.WriteStartElement("movie");
+
+                        if (!string.IsNullOrWhiteSpace(timer.Name))
+                        {
+                            writer.WriteElementString("title", timer.Name);
+                        }
                     }
                     }
 
 
                     writer.WriteElementString("dateadded", DateTime.UtcNow.ToLocalTime().ToString(DateAddedFormat));
                     writer.WriteElementString("dateadded", DateTime.UtcNow.ToLocalTime().ToString(DateAddedFormat));
@@ -1645,25 +1700,15 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                         .Replace("&quot;", "'");
                         .Replace("&quot;", "'");
 
 
                     writer.WriteElementString("plot", overview);
                     writer.WriteElementString("plot", overview);
-                    writer.WriteElementString("lockdata", true.ToString().ToLower());
 
 
-                    if (timer.CommunityRating.HasValue)
+                    if (lockData)
                     {
                     {
-                        writer.WriteElementString("rating", timer.CommunityRating.Value.ToString(CultureInfo.InvariantCulture));
+                        writer.WriteElementString("lockdata", true.ToString().ToLower());
                     }
                     }
 
 
-                    if (timer.IsSports)
-                    {
-                        AddGenre(timer.Genres, "Sports");
-                    }
-                    if (timer.IsKids)
-                    {
-                        AddGenre(timer.Genres, "Kids");
-                        AddGenre(timer.Genres, "Children");
-                    }
-                    if (timer.IsNews)
+                    if (timer.CommunityRating.HasValue)
                     {
                     {
-                        AddGenre(timer.Genres, "News");
+                        writer.WriteElementString("rating", timer.CommunityRating.Value.ToString(CultureInfo.InvariantCulture));
                     }
                     }
 
 
                     foreach (var genre in timer.Genres)
                     foreach (var genre in timer.Genres)
@@ -1968,4 +2013,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             public CancellationTokenSource CancellationTokenSource { get; set; }
             public CancellationTokenSource CancellationTokenSource { get; set; }
         }
         }
     }
     }
+    public static class ConfigurationExtension
+    {
+        public static XbmcMetadataOptions GetNfoConfiguration(this IConfigurationManager manager)
+        {
+            return manager.GetConfiguration<XbmcMetadataOptions>("xbmcmetadata");
+        }
+    }
 }
 }

+ 1 - 2
Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs

@@ -54,9 +54,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             catch (FileNotFoundException)
             catch (FileNotFoundException)
             {
             {
             }
             }
-            catch (IOException ex)
+            catch (IOException)
             {
             {
-                Logger.ErrorException("Error deserializing {0}", ex, jsonFile);
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {

+ 16 - 4
Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs

@@ -269,6 +269,18 @@ namespace Emby.Server.Implementations.LiveTv
             return _libraryManager.GetNewItemId(name.ToLower(), typeof(ILiveTvRecording));
             return _libraryManager.GetNewItemId(name.ToLower(), typeof(ILiveTvRecording));
         }
         }
 
 
+        private string GetItemExternalId(BaseItem item)
+        {
+            var externalId = item.ExternalId;
+
+            if (string.IsNullOrWhiteSpace(externalId))
+            {
+                externalId = item.GetProviderId("ProviderExternalId");
+            }
+
+            return externalId;
+        }
+
         public async Task<TimerInfo> GetTimerInfo(TimerInfoDto dto, bool isNew, LiveTvManager liveTv, CancellationToken cancellationToken)
         public async Task<TimerInfo> GetTimerInfo(TimerInfoDto dto, bool isNew, LiveTvManager liveTv, CancellationToken cancellationToken)
         {
         {
             var info = new TimerInfo
             var info = new TimerInfo
@@ -304,7 +316,7 @@ namespace Emby.Server.Implementations.LiveTv
 
 
                 if (channel != null)
                 if (channel != null)
                 {
                 {
-                    info.ChannelId = channel.ExternalId;
+                    info.ChannelId = GetItemExternalId(channel);
                 }
                 }
             }
             }
 
 
@@ -314,7 +326,7 @@ namespace Emby.Server.Implementations.LiveTv
 
 
                 if (program != null)
                 if (program != null)
                 {
                 {
-                    info.ProgramId = program.ExternalId;
+                    info.ProgramId = GetItemExternalId(program);
                 }
                 }
             }
             }
 
 
@@ -370,7 +382,7 @@ namespace Emby.Server.Implementations.LiveTv
 
 
                 if (channel != null)
                 if (channel != null)
                 {
                 {
-                    info.ChannelId = channel.ExternalId;
+                    info.ChannelId = GetItemExternalId(channel);
                 }
                 }
             }
             }
 
 
@@ -380,7 +392,7 @@ namespace Emby.Server.Implementations.LiveTv
 
 
                 if (program != null)
                 if (program != null)
                 {
                 {
-                    info.ProgramId = program.ExternalId;
+                    info.ProgramId = GetItemExternalId(program);
                 }
                 }
             }
             }
 
 

+ 50 - 17
Emby.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -251,12 +251,24 @@ namespace Emby.Server.Implementations.LiveTv
             return await GetLiveStream(id, mediaSourceId, true, cancellationToken).ConfigureAwait(false);
             return await GetLiveStream(id, mediaSourceId, true, cancellationToken).ConfigureAwait(false);
         }
         }
 
 
+        private string GetItemExternalId(BaseItem item)
+        {
+            var externalId = item.ExternalId;
+
+            if (string.IsNullOrWhiteSpace(externalId))
+            {
+                externalId = item.GetProviderId("ProviderExternalId");
+            }
+
+            return externalId;
+        }
+
         public async Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(IHasMediaSources item, CancellationToken cancellationToken)
         public async Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(IHasMediaSources item, CancellationToken cancellationToken)
         {
         {
             var baseItem = (BaseItem)item;
             var baseItem = (BaseItem)item;
             var service = GetService(baseItem);
             var service = GetService(baseItem);
 
 
-            return await service.GetRecordingStreamMediaSources(baseItem.ExternalId, cancellationToken).ConfigureAwait(false);
+            return await service.GetRecordingStreamMediaSources(GetItemExternalId(baseItem), cancellationToken).ConfigureAwait(false);
         }
         }
 
 
         public async Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(IHasMediaSources item, CancellationToken cancellationToken)
         public async Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(IHasMediaSources item, CancellationToken cancellationToken)
@@ -313,18 +325,18 @@ namespace Emby.Server.Implementations.LiveTv
                 var channel = GetInternalChannel(id);
                 var channel = GetInternalChannel(id);
                 isVideo = channel.ChannelType == ChannelType.TV;
                 isVideo = channel.ChannelType == ChannelType.TV;
                 service = GetService(channel);
                 service = GetService(channel);
-                _logger.Info("Opening channel stream from {0}, external channel Id: {1}", service.Name, channel.ExternalId);
+                _logger.Info("Opening channel stream from {0}, external channel Id: {1}", service.Name, GetItemExternalId(channel));
 
 
                 var supportsManagedStream = service as ISupportsDirectStreamProvider;
                 var supportsManagedStream = service as ISupportsDirectStreamProvider;
                 if (supportsManagedStream != null)
                 if (supportsManagedStream != null)
                 {
                 {
-                    var streamInfo = await supportsManagedStream.GetChannelStreamWithDirectStreamProvider(channel.ExternalId, mediaSourceId, cancellationToken).ConfigureAwait(false);
+                    var streamInfo = await supportsManagedStream.GetChannelStreamWithDirectStreamProvider(GetItemExternalId(channel), mediaSourceId, cancellationToken).ConfigureAwait(false);
                     info = streamInfo.Item1;
                     info = streamInfo.Item1;
                     directStreamProvider = streamInfo.Item2;
                     directStreamProvider = streamInfo.Item2;
                 }
                 }
                 else
                 else
                 {
                 {
-                    info = await service.GetChannelStream(channel.ExternalId, mediaSourceId, cancellationToken).ConfigureAwait(false);
+                    info = await service.GetChannelStream(GetItemExternalId(channel), mediaSourceId, cancellationToken).ConfigureAwait(false);
                 }
                 }
                 info.RequiresClosing = true;
                 info.RequiresClosing = true;
 
 
@@ -341,8 +353,8 @@ namespace Emby.Server.Implementations.LiveTv
                 isVideo = !string.Equals(recording.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase);
                 isVideo = !string.Equals(recording.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase);
                 service = GetService(recording);
                 service = GetService(recording);
 
 
-                _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.ExternalId);
-                info = await service.GetRecordingStream(recording.ExternalId, null, cancellationToken).ConfigureAwait(false);
+                _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, GetItemExternalId(recording));
+                info = await service.GetRecordingStream(GetItemExternalId(recording), null, cancellationToken).ConfigureAwait(false);
                 info.RequiresClosing = true;
                 info.RequiresClosing = true;
 
 
                 if (info.RequiresClosing)
                 if (info.RequiresClosing)
@@ -493,7 +505,7 @@ namespace Emby.Server.Implementations.LiveTv
                 isNew = true;
                 isNew = true;
             }
             }
 
 
-            if (!string.Equals(channelInfo.Id, item.ExternalId))
+            if (!string.Equals(channelInfo.Id, item.ExternalId, StringComparison.Ordinal))
             {
             {
                 isNew = true;
                 isNew = true;
             }
             }
@@ -601,7 +613,6 @@ namespace Emby.Server.Implementations.LiveTv
 
 
             item.EpisodeTitle = info.EpisodeTitle;
             item.EpisodeTitle = info.EpisodeTitle;
             item.ExternalId = info.Id;
             item.ExternalId = info.Id;
-            item.ExternalSeriesIdLegacy = seriesId;
 
 
             if (!string.IsNullOrWhiteSpace(seriesId) && !string.Equals(item.ExternalSeriesId, seriesId, StringComparison.Ordinal))
             if (!string.IsNullOrWhiteSpace(seriesId) && !string.Equals(item.ExternalSeriesId, seriesId, StringComparison.Ordinal))
             {
             {
@@ -841,6 +852,13 @@ namespace Emby.Server.Implementations.LiveTv
             return item.Id;
             return item.Id;
         }
         }
 
 
+
+
+        private string GetExternalSeriesIdLegacy(BaseItem item)
+        {
+            return item.GetProviderId("ProviderExternalSeriesId");
+        }
+
         public async Task<BaseItemDto> GetProgram(string id, CancellationToken cancellationToken, User user = null)
         public async Task<BaseItemDto> GetProgram(string id, CancellationToken cancellationToken, User user = null)
         {
         {
             var program = GetInternalProgram(id);
             var program = GetInternalProgram(id);
@@ -848,7 +866,15 @@ namespace Emby.Server.Implementations.LiveTv
             var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user);
             var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user);
 
 
             var list = new List<Tuple<BaseItemDto, string, string, string>>();
             var list = new List<Tuple<BaseItemDto, string, string, string>>();
-            list.Add(new Tuple<BaseItemDto, string, string, string>(dto, program.ServiceName, program.ExternalId, program.ExternalSeriesIdLegacy));
+
+            var externalSeriesId = program.ExternalSeriesId;
+
+            if (string.IsNullOrWhiteSpace(externalSeriesId))
+            {
+                externalSeriesId = GetExternalSeriesIdLegacy(program);
+            }
+
+            list.Add(new Tuple<BaseItemDto, string, string, string>(dto, program.ServiceName, GetItemExternalId(program), externalSeriesId));
 
 
             await AddRecordingInfo(list, cancellationToken).ConfigureAwait(false);
             await AddRecordingInfo(list, cancellationToken).ConfigureAwait(false);
 
 
@@ -1283,7 +1309,7 @@ namespace Emby.Server.Implementations.LiveTv
                     var isKids = false;
                     var isKids = false;
                     var iSSeries = false;
                     var iSSeries = false;
 
 
-                    var channelPrograms = await service.GetProgramsAsync(currentChannel.ExternalId, start, end, cancellationToken).ConfigureAwait(false);
+                    var channelPrograms = await service.GetProgramsAsync(GetItemExternalId(currentChannel), start, end, cancellationToken).ConfigureAwait(false);
 
 
                     var existingPrograms = _libraryManager.GetItemList(new InternalItemsQuery
                     var existingPrograms = _libraryManager.GetItemList(new InternalItemsQuery
                     {
                     {
@@ -1830,7 +1856,14 @@ namespace Emby.Server.Implementations.LiveTv
                     dto.ServiceName = serviceName;
                     dto.ServiceName = serviceName;
                 }
                 }
 
 
-                programTuples.Add(new Tuple<BaseItemDto, string, string, string>(dto, serviceName, program.ExternalId, program.ExternalSeriesIdLegacy));
+                var externalSeriesId = program.ExternalSeriesId;
+
+                if (string.IsNullOrWhiteSpace(externalSeriesId))
+                {
+                    externalSeriesId = GetExternalSeriesIdLegacy(program);
+                }
+
+                programTuples.Add(new Tuple<BaseItemDto, string, string, string>(dto, serviceName, GetItemExternalId(program), externalSeriesId));
             }
             }
 
 
             await AddRecordingInfo(programTuples, CancellationToken.None).ConfigureAwait(false);
             await AddRecordingInfo(programTuples, CancellationToken.None).ConfigureAwait(false);
@@ -2006,7 +2039,7 @@ namespace Emby.Server.Implementations.LiveTv
             if (service is EmbyTV.EmbyTV)
             if (service is EmbyTV.EmbyTV)
             {
             {
                 // We can't trust that we'll be able to direct stream it through emby server,  no matter what the provider says
                 // We can't trust that we'll be able to direct stream it through emby server,  no matter what the provider says
-                return service.DeleteRecordingAsync(recording.ExternalId, CancellationToken.None);
+                return service.DeleteRecordingAsync(GetItemExternalId(recording), CancellationToken.None);
             }
             }
 
 
             return Task.FromResult(true);
             return Task.FromResult(true);
@@ -2030,7 +2063,7 @@ namespace Emby.Server.Implementations.LiveTv
 
 
             try
             try
             {
             {
-                await service.DeleteRecordingAsync(recording.ExternalId, CancellationToken.None).ConfigureAwait(false);
+                await service.DeleteRecordingAsync(GetItemExternalId(recording), CancellationToken.None).ConfigureAwait(false);
             }
             }
             catch (ResourceNotFoundException)
             catch (ResourceNotFoundException)
             {
             {
@@ -2289,12 +2322,12 @@ namespace Emby.Server.Implementations.LiveTv
                 programInfo = new ProgramInfo
                 programInfo = new ProgramInfo
                 {
                 {
                     Audio = program.Audio,
                     Audio = program.Audio,
-                    ChannelId = channel.ExternalId,
+                    ChannelId = GetItemExternalId(channel),
                     CommunityRating = program.CommunityRating,
                     CommunityRating = program.CommunityRating,
                     EndDate = program.EndDate ?? DateTime.MinValue,
                     EndDate = program.EndDate ?? DateTime.MinValue,
                     EpisodeTitle = program.EpisodeTitle,
                     EpisodeTitle = program.EpisodeTitle,
                     Genres = program.Genres,
                     Genres = program.Genres,
-                    Id = program.ExternalId,
+                    Id = GetItemExternalId(program),
                     IsHD = program.IsHD,
                     IsHD = program.IsHD,
                     IsKids = program.IsKids,
                     IsKids = program.IsKids,
                     IsLive = program.IsLive,
                     IsLive = program.IsLive,
@@ -2360,7 +2393,7 @@ namespace Emby.Server.Implementations.LiveTv
             info.Name = program.Name;
             info.Name = program.Name;
             info.Overview = program.Overview;
             info.Overview = program.Overview;
             info.ProgramId = programDto.Id;
             info.ProgramId = programDto.Id;
-            info.ExternalProgramId = program.ExternalId;
+            info.ExternalProgramId = GetItemExternalId(program);
 
 
             if (program.EndDate.HasValue)
             if (program.EndDate.HasValue)
             {
             {
@@ -2804,7 +2837,7 @@ namespace Emby.Server.Implementations.LiveTv
 
 
         public async Task<ListingsProviderInfo> SaveListingProvider(ListingsProviderInfo info, bool validateLogin, bool validateListings)
         public async Task<ListingsProviderInfo> SaveListingProvider(ListingsProviderInfo info, bool validateLogin, bool validateListings)
         {
         {
-            info = _jsonSerializer.DeserializeFromString< ListingsProviderInfo>(_jsonSerializer.SerializeToString(info));
+            info = _jsonSerializer.DeserializeFromString<ListingsProviderInfo>(_jsonSerializer.SerializeToString(info));
 
 
             var provider = _listingProviders.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase));
             var provider = _listingProviders.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase));
 
 

+ 13 - 1
Emby.Server.Implementations/LiveTv/ProgramImageProvider.cs

@@ -24,6 +24,18 @@ namespace Emby.Server.Implementations.LiveTv
             return new[] { ImageType.Primary };
             return new[] { ImageType.Primary };
         }
         }
 
 
+        private string GetItemExternalId(BaseItem item)
+        {
+            var externalId = item.ExternalId;
+
+            if (string.IsNullOrWhiteSpace(externalId))
+            {
+                externalId = item.GetProviderId("ProviderExternalId");
+            }
+
+            return externalId;
+        }
+
         public async Task<DynamicImageResponse> GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken)
         public async Task<DynamicImageResponse> GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken)
         {
         {
             var liveTvItem = (LiveTvProgram)item;
             var liveTvItem = (LiveTvProgram)item;
@@ -38,7 +50,7 @@ namespace Emby.Server.Implementations.LiveTv
                 {
                 {
                     var channel = _liveTvManager.GetInternalChannel(liveTvItem.ChannelId);
                     var channel = _liveTvManager.GetInternalChannel(liveTvItem.ChannelId);
 
 
-                    var response = await service.GetProgramImageAsync(liveTvItem.ExternalId, channel.ExternalId, cancellationToken).ConfigureAwait(false);
+                    var response = await service.GetProgramImageAsync(GetItemExternalId(liveTvItem), GetItemExternalId(channel), cancellationToken).ConfigureAwait(false);
 
 
                     if (response != null)
                     if (response != null)
                     {
                     {

+ 5 - 1
MediaBrowser.Api/ApiEntryPoint.cs

@@ -128,7 +128,11 @@ namespace MediaBrowser.Api
             {
             {
                 // Don't clutter the log
                 // Don't clutter the log
             }
             }
-            catch (IOException ex)
+            catch (IOException)
+            {
+                // Don't clutter the log
+            }
+            catch (Exception ex)
             {
             {
                 Logger.ErrorException("Error deleting encoded media cache", ex);
                 Logger.ErrorException("Error deleting encoded media cache", ex);
             }
             }

+ 0 - 6
MediaBrowser.Common/Configuration/IApplicationPaths.cs

@@ -6,12 +6,6 @@ namespace MediaBrowser.Common.Configuration
     /// </summary>
     /// </summary>
     public interface IApplicationPaths
     public interface IApplicationPaths
     {
     {
-        /// <summary>
-        /// Gets the application path.
-        /// </summary>
-        /// <value>The application path.</value>
-        string ApplicationPath { get; }
-
         /// <summary>
         /// <summary>
         /// Gets the path to the program data folder
         /// Gets the path to the program data folder
         /// </summary>
         /// </summary>

+ 1 - 18
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -296,28 +296,11 @@ namespace MediaBrowser.Controller.Entities
         /// If this content came from an external service, the id of the content on that service
         /// If this content came from an external service, the id of the content on that service
         /// </summary>
         /// </summary>
         [IgnoreDataMember]
         [IgnoreDataMember]
-        public string ExternalId
-        {
-            get { return this.GetProviderId("ProviderExternalId"); }
-            set
-            {
-                this.SetProviderId("ProviderExternalId", value);
-            }
-        }
+        public string ExternalId { get; set; }
 
 
         [IgnoreDataMember]
         [IgnoreDataMember]
         public string ExternalSeriesId { get; set; }
         public string ExternalSeriesId { get; set; }
 
 
-        [IgnoreDataMember]
-        public string ExternalSeriesIdLegacy
-        {
-            get { return this.GetProviderId("ProviderExternalSeriesId"); }
-            set
-            {
-                this.SetProviderId("ProviderExternalSeriesId", value);
-            }
-        }
-
         /// <summary>
         /// <summary>
         /// Gets or sets the etag.
         /// Gets or sets the etag.
         /// </summary>
         /// </summary>

+ 9 - 7
MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs

@@ -37,20 +37,22 @@ namespace MediaBrowser.MediaEncoding.Encoder
             {
             {
                 output = GetProcessOutput(encoderAppPath, "-version");
                 output = GetProcessOutput(encoderAppPath, "-version");
             }
             }
-            catch
+            catch (Exception ex)
             {
             {
+                if (logOutput)
+                {
+                    _logger.ErrorException("Error validating encoder", ex);
+                }
             }
             }
 
 
-            output = output ?? string.Empty;
-
-            if (logOutput)
+            if (string.IsNullOrWhiteSpace(output))
             {
             {
-                _logger.Info("ffmpeg info: {0}", output);
+                return false;
             }
             }
 
 
-            if (string.IsNullOrWhiteSpace(output))
+            if (logOutput)
             {
             {
-                return false;
+                _logger.Info("ffmpeg info: {0}", output);
             }
             }
 
 
             if (output.IndexOf("Libav developers", StringComparison.OrdinalIgnoreCase) != -1)
             if (output.IndexOf("Libav developers", StringComparison.OrdinalIgnoreCase) != -1)

+ 1 - 0
MediaBrowser.Model/IO/IFileSystem.cs

@@ -308,6 +308,7 @@ namespace MediaBrowser.Model.IO
         void SetReadOnly(string path, bool isHidden);
         void SetReadOnly(string path, bool isHidden);
 
 
         char DirectorySeparatorChar { get; }
         char DirectorySeparatorChar { get; }
+        char PathSeparator { get; }
 
 
         string GetFullPath(string path);
         string GetFullPath(string path);
 
 

+ 2 - 0
MediaBrowser.Model/System/IEnvironmentInfo.cs

@@ -12,6 +12,8 @@ namespace MediaBrowser.Model.System
         string OperatingSystemName { get; }
         string OperatingSystemName { get; }
         string OperatingSystemVersion { get; }
         string OperatingSystemVersion { get; }
         Architecture SystemArchitecture { get; }
         Architecture SystemArchitecture { get; }
+        string GetEnvironmentVariable(string name);
+        string GetUserId();
     }
     }
 
 
     public enum OperatingSystem
     public enum OperatingSystem

+ 1 - 1
MediaBrowser.Server.Mono/MonoAppHost.cs

@@ -91,7 +91,7 @@ namespace MediaBrowser.Server.Mono
             MainClass.Shutdown();
             MainClass.Shutdown();
         }
         }
 
 
-        protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory)
+        protected override void AuthorizeServer()
         {
         {
             throw new NotImplementedException();
             throw new NotImplementedException();
         }
         }

+ 9 - 1
MediaBrowser.Server.Mono/Program.cs

@@ -5,6 +5,7 @@ using MediaBrowser.Server.Startup.Common;
 using Microsoft.Win32;
 using Microsoft.Win32;
 using System;
 using System;
 using System.Diagnostics;
 using System.Diagnostics;
+using System.Globalization;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Net;
 using System.Net;
@@ -74,7 +75,9 @@ namespace MediaBrowser.Server.Mono
                 programDataPath = ApplicationPathHelper.GetProgramDataPath(applicationPath);
                 programDataPath = ApplicationPathHelper.GetProgramDataPath(applicationPath);
             }
             }
 
 
-            return new ServerApplicationPaths(programDataPath, applicationPath, Path.GetDirectoryName(applicationPath));
+            var appFolderPath = Path.GetDirectoryName(applicationPath);
+
+            return new ServerApplicationPaths(programDataPath, appFolderPath, Path.GetDirectoryName(applicationPath));
         }
         }
 
 
         private static readonly TaskCompletionSource<bool> ApplicationTaskCompletionSource = new TaskCompletionSource<bool>();
         private static readonly TaskCompletionSource<bool> ApplicationTaskCompletionSource = new TaskCompletionSource<bool>();
@@ -305,5 +308,10 @@ namespace MediaBrowser.Server.Mono
     public class MonoEnvironmentInfo : EnvironmentInfo
     public class MonoEnvironmentInfo : EnvironmentInfo
     {
     {
         public bool IsBsd { get; set; }
         public bool IsBsd { get; set; }
+
+        public virtual string GetUserId()
+        {
+            return Syscall.getuid().ToString(CultureInfo.InvariantCulture);
+        }
     }
     }
 }
 }

+ 5 - 1
MediaBrowser.Server.Startup.Common/Persistence/SqliteExtensions.cs

@@ -14,7 +14,11 @@ namespace Emby.Server.Core.Data
         /// <summary>
         /// <summary>
         /// Connects to db.
         /// Connects to db.
         /// </summary>
         /// </summary>
-        public static async Task<IDbConnection> ConnectToDb(string dbPath, bool isReadOnly, bool enablePooling, int? cacheSize, ILogger logger)
+        public static async Task<IDbConnection> ConnectToDb(string dbPath, 
+            bool isReadOnly, 
+            bool enablePooling, 
+            int? cacheSize, 
+            ILogger logger)
         {
         {
             if (string.IsNullOrEmpty(dbPath))
             if (string.IsNullOrEmpty(dbPath))
             {
             {

+ 16 - 12
MediaBrowser.ServerApplication/MainStartup.cs

@@ -44,6 +44,8 @@ namespace MediaBrowser.ServerApplication
         [DllImport("kernel32.dll", SetLastError = true)]
         [DllImport("kernel32.dll", SetLastError = true)]
         static extern bool SetDllDirectory(string lpPathName);
         static extern bool SetDllDirectory(string lpPathName);
 
 
+        public static string ApplicationPath;
+
         public static bool TryGetLocalFromUncDirectory(string local, out string unc)
         public static bool TryGetLocalFromUncDirectory(string local, out string unc)
         {
         {
             if ((local == null) || (local == ""))
             if ((local == null) || (local == ""))
@@ -81,14 +83,14 @@ namespace MediaBrowser.ServerApplication
 
 
             var currentProcess = Process.GetCurrentProcess();
             var currentProcess = Process.GetCurrentProcess();
 
 
-            var applicationPath = currentProcess.MainModule.FileName;
-            var architecturePath = Path.Combine(Path.GetDirectoryName(applicationPath), Environment.Is64BitProcess ? "x64" : "x86");
+            ApplicationPath = currentProcess.MainModule.FileName;
+            var architecturePath = Path.Combine(Path.GetDirectoryName(ApplicationPath), Environment.Is64BitProcess ? "x64" : "x86");
 
 
             Wand.SetMagickCoderModulePath(architecturePath);
             Wand.SetMagickCoderModulePath(architecturePath);
 
 
             var success = SetDllDirectory(architecturePath);
             var success = SetDllDirectory(architecturePath);
 
 
-            var appPaths = CreateApplicationPaths(applicationPath, IsRunningAsService);
+            var appPaths = CreateApplicationPaths(ApplicationPath, IsRunningAsService);
 
 
             var logManager = new NlogManager(appPaths.LogDirectoryPath, "server");
             var logManager = new NlogManager(appPaths.LogDirectoryPath, "server");
             logManager.ReloadLogger(LogSeverity.Debug);
             logManager.ReloadLogger(LogSeverity.Debug);
@@ -102,7 +104,7 @@ namespace MediaBrowser.ServerApplication
             if (options.ContainsOption("-installservice"))
             if (options.ContainsOption("-installservice"))
             {
             {
                 logger.Info("Performing service installation");
                 logger.Info("Performing service installation");
-                InstallService(applicationPath, logger);
+                InstallService(ApplicationPath, logger);
                 return;
                 return;
             }
             }
 
 
@@ -110,7 +112,7 @@ namespace MediaBrowser.ServerApplication
             if (options.ContainsOption("-installserviceasadmin"))
             if (options.ContainsOption("-installserviceasadmin"))
             {
             {
                 logger.Info("Performing service installation");
                 logger.Info("Performing service installation");
-                RunServiceInstallation(applicationPath);
+                RunServiceInstallation(ApplicationPath);
                 return;
                 return;
             }
             }
 
 
@@ -118,7 +120,7 @@ namespace MediaBrowser.ServerApplication
             if (options.ContainsOption("-uninstallservice"))
             if (options.ContainsOption("-uninstallservice"))
             {
             {
                 logger.Info("Performing service uninstallation");
                 logger.Info("Performing service uninstallation");
-                UninstallService(applicationPath, logger);
+                UninstallService(ApplicationPath, logger);
                 return;
                 return;
             }
             }
 
 
@@ -126,15 +128,15 @@ namespace MediaBrowser.ServerApplication
             if (options.ContainsOption("-uninstallserviceasadmin"))
             if (options.ContainsOption("-uninstallserviceasadmin"))
             {
             {
                 logger.Info("Performing service uninstallation");
                 logger.Info("Performing service uninstallation");
-                RunServiceUninstallation(applicationPath);
+                RunServiceUninstallation(ApplicationPath);
                 return;
                 return;
             }
             }
 
 
             AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
             AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
 
 
-            RunServiceInstallationIfNeeded(applicationPath);
+            RunServiceInstallationIfNeeded(ApplicationPath);
 
 
-            if (IsAlreadyRunning(applicationPath, currentProcess))
+            if (IsAlreadyRunning(ApplicationPath, currentProcess))
             {
             {
                 logger.Info("Shutting down because another instance of Emby Server is already running.");
                 logger.Info("Shutting down because another instance of Emby Server is already running.");
                 return;
                 return;
@@ -250,6 +252,8 @@ namespace MediaBrowser.ServerApplication
         /// <returns>ServerApplicationPaths.</returns>
         /// <returns>ServerApplicationPaths.</returns>
         private static ServerApplicationPaths CreateApplicationPaths(string applicationPath, bool runAsService)
         private static ServerApplicationPaths CreateApplicationPaths(string applicationPath, bool runAsService)
         {
         {
+            var appFolderPath = Path.GetDirectoryName(applicationPath);
+
             var resourcesPath = Path.GetDirectoryName(applicationPath);
             var resourcesPath = Path.GetDirectoryName(applicationPath);
 
 
             if (runAsService)
             if (runAsService)
@@ -258,10 +262,10 @@ namespace MediaBrowser.ServerApplication
 
 
                 var programDataPath = Path.GetDirectoryName(systemPath);
                 var programDataPath = Path.GetDirectoryName(systemPath);
 
 
-                return new ServerApplicationPaths(programDataPath, applicationPath, resourcesPath);
+                return new ServerApplicationPaths(programDataPath, appFolderPath, resourcesPath);
             }
             }
 
 
-            return new ServerApplicationPaths(ApplicationPathHelper.GetProgramDataPath(applicationPath), applicationPath, resourcesPath);
+            return new ServerApplicationPaths(ApplicationPathHelper.GetProgramDataPath(applicationPath), appFolderPath, resourcesPath);
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -663,7 +667,7 @@ namespace MediaBrowser.ServerApplication
 
 
                 _logger.Info("Starting new instance");
                 _logger.Info("Starting new instance");
                 //Application.Restart();
                 //Application.Restart();
-                Process.Start(_appHost.ServerConfigurationManager.ApplicationPaths.ApplicationPath);
+                Process.Start(ApplicationPath);
 
 
                 ShutdownWindowsApplication();
                 ShutdownWindowsApplication();
             }
             }

+ 1 - 1
MediaBrowser.ServerApplication/Updates/ApplicationUpdater.cs

@@ -44,7 +44,7 @@ namespace MediaBrowser.ServerApplication.Updates
             // startpath = executable to launch
             // startpath = executable to launch
             // systempath = folder containing installation
             // systempath = folder containing installation
             var args = string.Format("product={0} archive=\"{1}\" caller={2} pismo=false version={3} service={4} installpath=\"{5}\" startpath=\"{6}\" systempath=\"{7}\"",
             var args = string.Format("product={0} archive=\"{1}\" caller={2} pismo=false version={3} service={4} installpath=\"{5}\" startpath=\"{6}\" systempath=\"{7}\"",
-                    product, archive, Process.GetCurrentProcess().Id, version, restartServiceName ?? string.Empty, appPaths.ProgramDataPath, appPaths.ApplicationPath, systemPath);
+                    product, archive, Process.GetCurrentProcess().Id, version, restartServiceName ?? string.Empty, appPaths.ProgramDataPath, MainStartup.ApplicationPath, systemPath);
 
 
             logger.Info("Args: {0}", args);
             logger.Info("Args: {0}", args);
             Process.Start(tempUpdater, args);
             Process.Start(tempUpdater, args);

+ 7 - 2
MediaBrowser.ServerApplication/WindowsAppHost.cs

@@ -6,6 +6,7 @@ using System.Reflection;
 using Emby.Server.Core;
 using Emby.Server.Core;
 using Emby.Server.Core.Data;
 using Emby.Server.Core.Data;
 using Emby.Server.Core.FFMpeg;
 using Emby.Server.Core.FFMpeg;
+using Emby.Server.Implementations.EntryPoints;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.System;
 using MediaBrowser.Model.System;
@@ -60,9 +61,13 @@ namespace MediaBrowser.ServerApplication
             MainStartup.Shutdown();
             MainStartup.Shutdown();
         }
         }
 
 
-        protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory)
+        protected override void AuthorizeServer()
         {
         {
-            ServerAuthorization.AuthorizeServer(udpPort, httpServerPort, httpsServerPort, applicationPath, tempDirectory);
+            ServerAuthorization.AuthorizeServer(UdpServerEntryPoint.PortNumber,
+                    ServerConfigurationManager.Configuration.HttpServerPortNumber,
+                    ServerConfigurationManager.Configuration.HttpsPortNumber,
+                    MainStartup.ApplicationPath,
+                    ConfigurationManager.CommonApplicationPaths.TempDirectory);
         }
         }
 
 
         protected override IDbConnector GetDbConnector()
         protected override IDbConnector GetDbConnector()

+ 0 - 2
MediaBrowser.XbmcMetadata/Savers/SeriesNfoSaver.cs

@@ -90,8 +90,6 @@ namespace MediaBrowser.XbmcMetadata.Savers
             }
             }
         }
         }
 
 
-        private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
         protected override List<string> GetTagsUsed()
         protected override List<string> GetTagsUsed()
         {
         {
             var list = new List<string>
             var list = new List<string>

+ 1 - 1
Nuget/MediaBrowser.Common.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
     <metadata>
         <id>MediaBrowser.Common</id>
         <id>MediaBrowser.Common</id>
-        <version>3.0.689</version>
+        <version>3.0.691</version>
         <title>Emby.Common</title>
         <title>Emby.Common</title>
         <authors>Emby Team</authors>
         <authors>Emby Team</authors>
         <owners>ebr,Luke,scottisafool</owners>
         <owners>ebr,Luke,scottisafool</owners>

+ 2 - 2
Nuget/MediaBrowser.Server.Core.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
     <metadata>
     <metadata>
         <id>MediaBrowser.Server.Core</id>
         <id>MediaBrowser.Server.Core</id>
-        <version>3.0.689</version>
+        <version>3.0.691</version>
         <title>Emby.Server.Core</title>
         <title>Emby.Server.Core</title>
         <authors>Emby Team</authors>
         <authors>Emby Team</authors>
         <owners>ebr,Luke,scottisafool</owners>
         <owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
         <description>Contains core components required to build plugins for Emby Server.</description>
         <description>Contains core components required to build plugins for Emby Server.</description>
         <copyright>Copyright © Emby 2013</copyright>
         <copyright>Copyright © Emby 2013</copyright>
         <dependencies>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.689" />
+            <dependency id="MediaBrowser.Common" version="3.0.691" />
         </dependencies>
         </dependencies>
     </metadata>
     </metadata>
     <files>
     <files>

+ 2 - 9
src/Emby.Server/ApplicationPathHelper.cs

@@ -8,7 +8,7 @@ namespace Emby.Server
 {
 {
     public class ApplicationPathHelper
     public class ApplicationPathHelper
     {
     {
-        public static string GetProgramDataPath(string applicationPath)
+        public static string GetProgramDataPath(string appDirectory)
         {
         {
             var useDebugPath = false;
             var useDebugPath = false;
 
 
@@ -27,14 +27,7 @@ namespace Emby.Server
             // If it's a relative path, e.g. "..\"
             // If it's a relative path, e.g. "..\"
             if (!Path.IsPathRooted(programDataPath))
             if (!Path.IsPathRooted(programDataPath))
             {
             {
-                var path = Path.GetDirectoryName(applicationPath);
-
-                if (string.IsNullOrEmpty(path))
-                {
-                    throw new Exception("Unable to determine running assembly location");
-                }
-
-                programDataPath = Path.Combine(path, programDataPath);
+                programDataPath = Path.Combine(appDirectory, programDataPath);
 
 
                 programDataPath = Path.GetFullPath(programDataPath);
                 programDataPath = Path.GetFullPath(programDataPath);
             }
             }

+ 1 - 1
src/Emby.Server/CoreAppHost.cs

@@ -51,7 +51,7 @@ namespace Emby.Server
             return list;
             return list;
         }
         }
 
 
-        protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory)
+        protected override void AuthorizeServer()
         {
         {
         }
         }
 
 

+ 34 - 179
src/Emby.Server/Program.cs

@@ -28,8 +28,6 @@ namespace Emby.Server
 
 
         private static ILogger _logger;
         private static ILogger _logger;
 
 
-        private static bool _isRunningAsService = false;
-        private static bool _canRestartService = false;
         private static bool _appHostDisposed;
         private static bool _appHostDisposed;
 
 
         [DllImport("kernel32.dll", SetLastError = true)]
         [DllImport("kernel32.dll", SetLastError = true)]
@@ -41,39 +39,33 @@ namespace Emby.Server
         public static void Main(string[] args)
         public static void Main(string[] args)
         {
         {
             var options = new StartupOptions();
             var options = new StartupOptions();
-            _isRunningAsService = options.ContainsOption("-service");
-
-            if (_isRunningAsService)
-            {
-                //_canRestartService = CanRestartWindowsService();
-            }
 
 
             var currentProcess = Process.GetCurrentProcess();
             var currentProcess = Process.GetCurrentProcess();
-
-            var applicationPath = currentProcess.MainModule.FileName;
+            
+            var baseDirectory = System.AppContext.BaseDirectory;
             //var architecturePath = Path.Combine(Path.GetDirectoryName(applicationPath), Environment.Is64BitProcess ? "x64" : "x86");
             //var architecturePath = Path.Combine(Path.GetDirectoryName(applicationPath), Environment.Is64BitProcess ? "x64" : "x86");
 
 
             //Wand.SetMagickCoderModulePath(architecturePath);
             //Wand.SetMagickCoderModulePath(architecturePath);
 
 
             //var success = SetDllDirectory(architecturePath);
             //var success = SetDllDirectory(architecturePath);
 
 
-            var appPaths = CreateApplicationPaths(applicationPath, _isRunningAsService);
+            var appPaths = CreateApplicationPaths(baseDirectory);
 
 
             var logManager = new NlogManager(appPaths.LogDirectoryPath, "server");
             var logManager = new NlogManager(appPaths.LogDirectoryPath, "server");
             logManager.ReloadLogger(LogSeverity.Debug);
             logManager.ReloadLogger(LogSeverity.Debug);
             logManager.AddConsoleOutput();
             logManager.AddConsoleOutput();
 
 
             var logger = _logger = logManager.GetLogger("Main");
             var logger = _logger = logManager.GetLogger("Main");
-
+            
             ApplicationHost.LogEnvironmentInfo(logger, appPaths, true);
             ApplicationHost.LogEnvironmentInfo(logger, appPaths, true);
 
 
             AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
             AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
 
 
-            if (IsAlreadyRunning(applicationPath, currentProcess))
-            {
-                logger.Info("Shutting down because another instance of Emby Server is already running.");
-                return;
-            }
+            //if (IsAlreadyRunning(applicationPath, currentProcess))
+            //{
+            //    logger.Info("Shutting down because another instance of Emby Server is already running.");
+            //    return;
+            //}
 
 
             if (PerformUpdateIfNeeded(appPaths, logger))
             if (PerformUpdateIfNeeded(appPaths, logger))
             {
             {
@@ -81,14 +73,7 @@ namespace Emby.Server
                 return;
                 return;
             }
             }
 
 
-            try
-            {
-                RunApplication(appPaths, logManager, _isRunningAsService, options);
-            }
-            finally
-            {
-                OnServiceShutdown();
-            }
+            RunApplication(appPaths, logManager, options);
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -139,34 +124,17 @@ namespace Emby.Server
                 }
                 }
             }
             }
 
 
-            if (!_isRunningAsService)
-            {
-                return false;
-            }
-
             return false;
             return false;
         }
         }
 
 
         /// <summary>
         /// <summary>
         /// Creates the application paths.
         /// Creates the application paths.
         /// </summary>
         /// </summary>
-        /// <param name="applicationPath">The application path.</param>
-        /// <param name="runAsService">if set to <c>true</c> [run as service].</param>
-        /// <returns>ServerApplicationPaths.</returns>
-        private static ServerApplicationPaths CreateApplicationPaths(string applicationPath, bool runAsService)
+        private static ServerApplicationPaths CreateApplicationPaths(string appDirectory)
         {
         {
-            var resourcesPath = Path.GetDirectoryName(applicationPath);
-
-            if (runAsService)
-            {
-                var systemPath = Path.GetDirectoryName(applicationPath);
-
-                var programDataPath = Path.GetDirectoryName(systemPath);
-
-                return new ServerApplicationPaths(programDataPath, applicationPath, resourcesPath);
-            }
+            var resourcesPath = appDirectory;
 
 
-            return new ServerApplicationPaths(ApplicationPathHelper.GetProgramDataPath(applicationPath), applicationPath, resourcesPath);
+            return new ServerApplicationPaths(ApplicationPathHelper.GetProgramDataPath(appDirectory), appDirectory, resourcesPath);
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -177,14 +145,7 @@ namespace Emby.Server
         {
         {
             get
             get
             {
             {
-                if (_isRunningAsService)
-                {
-                    return _canRestartService;
-                }
-                else
-                {
-                    return true;
-                }
+                return true;
             }
             }
         }
         }
 
 
@@ -196,14 +157,7 @@ namespace Emby.Server
         {
         {
             get
             get
             {
             {
-                if (_isRunningAsService)
-                {
-                    return _canRestartService;
-                }
-                else
-                {
-                    return true;
-                }
+                return false;
             }
             }
         }
         }
 
 
@@ -214,9 +168,8 @@ namespace Emby.Server
         /// </summary>
         /// </summary>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="logManager">The log manager.</param>
         /// <param name="logManager">The log manager.</param>
-        /// <param name="runService">if set to <c>true</c> [run service].</param>
         /// <param name="options">The options.</param>
         /// <param name="options">The options.</param>
-        private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, bool runService, StartupOptions options)
+        private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, StartupOptions options)
         {
         {
             var fileSystem = new ManagedFileSystem(logManager.GetLogger("FileSystem"), true, true, true);
             var fileSystem = new ManagedFileSystem(logManager.GetLogger("FileSystem"), true, true, true);
 
 
@@ -240,29 +193,19 @@ namespace Emby.Server
 
 
             var initProgress = new Progress<double>();
             var initProgress = new Progress<double>();
 
 
-            if (!runService)
-            {
-                // Not crazy about this but it's the only way to suppress ffmpeg crash dialog boxes
-                SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOALIGNMENTFAULTEXCEPT |
-                             ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX);
-            }
+            // Not crazy about this but it's the only way to suppress ffmpeg crash dialog boxes
+            SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOALIGNMENTFAULTEXCEPT |
+                         ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX);
 
 
             var task = _appHost.Init(initProgress);
             var task = _appHost.Init(initProgress);
             Task.WaitAll(task);
             Task.WaitAll(task);
 
 
             task = task.ContinueWith(new Action<Task>(a => _appHost.RunStartupTasks()), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent);
             task = task.ContinueWith(new Action<Task>(a => _appHost.RunStartupTasks()), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent);
 
 
-            if (runService)
-            {
-                StartService(logManager);
-            }
-            else
-            {
-                Task.WaitAll(task);
+            Task.WaitAll(task);
 
 
-                task = ApplicationTaskCompletionSource.Task;
-                Task.WaitAll(task);
-            }
+            task = ApplicationTaskCompletionSource.Task;
+            Task.WaitAll(task);
         }
         }
 
 
         private static void GenerateCertificate(string certPath, string certHost)
         private static void GenerateCertificate(string certPath, string certHost)
@@ -270,31 +213,6 @@ namespace Emby.Server
             //CertificateGenerator.CreateSelfSignCertificatePfx(certPath, certHost, _logger);
             //CertificateGenerator.CreateSelfSignCertificatePfx(certPath, certHost, _logger);
         }
         }
 
 
-        /// <summary>
-        /// Starts the service.
-        /// </summary>
-        private static void StartService(ILogManager logManager)
-        {
-        }
-
-        /// <summary>
-        /// Handles the Disposed event of the service control.
-        /// </summary>
-        /// <param name="sender">The source of the event.</param>
-        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
-        static void service_Disposed(object sender, EventArgs e)
-        {
-            ApplicationTaskCompletionSource.SetResult(true);
-            OnServiceShutdown();
-        }
-
-        private static void OnServiceShutdown()
-        {
-            _logger.Info("Shutting down");
-
-            DisposeAppHost();
-        }
-
         /// <summary>
         /// <summary>
         /// Handles the UnhandledException event of the CurrentDomain control.
         /// Handles the UnhandledException event of the CurrentDomain control.
         /// </summary>
         /// </summary>
@@ -306,10 +224,7 @@ namespace Emby.Server
 
 
             new UnhandledExceptionWriter(_appHost.ServerConfigurationManager.ApplicationPaths, _logger, _appHost.LogManager).Log(exception);
             new UnhandledExceptionWriter(_appHost.ServerConfigurationManager.ApplicationPaths, _logger, _appHost.LogManager).Log(exception);
 
 
-            if (!_isRunningAsService)
-            {
-                ShowMessageBox("Unhandled exception: " + exception.Message);
-            }
+            ShowMessageBox("Unhandled exception: " + exception.Message);
 
 
             if (!Debugger.IsAttached)
             if (!Debugger.IsAttached)
             {
             {
@@ -325,29 +240,6 @@ namespace Emby.Server
         /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
         /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
         private static bool PerformUpdateIfNeeded(ServerApplicationPaths appPaths, ILogger logger)
         private static bool PerformUpdateIfNeeded(ServerApplicationPaths appPaths, ILogger logger)
         {
         {
-            // Look for the existence of an update archive
-            var updateArchive = Path.Combine(appPaths.TempUpdatePath, "MBServer" + ".zip");
-            if (File.Exists(updateArchive))
-            {
-                logger.Info("An update is available from {0}", updateArchive);
-
-                // Update is there - execute update
-                try
-                {
-                    //var serviceName = _isRunningAsService ? BackgroundService.GetExistingServiceName() : string.Empty;
-                    //new ApplicationUpdater().UpdateApplication(appPaths, updateArchive, logger, serviceName);
-
-                    // And just let the app exit so it can update
-                    return true;
-                }
-                catch (Exception e)
-                {
-                    logger.ErrorException("Error starting updater.", e);
-
-                    ShowMessageBox(string.Format("Error attempting to update application.\n\n{0}\n\n{1}", e.GetType().Name, e.Message));
-                }
-            }
-
             return false;
             return false;
         }
         }
 
 
@@ -358,37 +250,25 @@ namespace Emby.Server
 
 
         public static void Shutdown()
         public static void Shutdown()
         {
         {
-            if (_isRunningAsService)
-            {
-                ShutdownWindowsService();
-            }
-            else
-            {
-                DisposeAppHost();
+            DisposeAppHost();
 
 
-                ShutdownWindowsApplication();
-            }
+            //_logger.Info("Calling Application.Exit");
+            //Application.Exit();
+
+            _logger.Info("Calling Environment.Exit");
+            Environment.Exit(0);
+
+            _logger.Info("Calling ApplicationTaskCompletionSource.SetResult");
+            ApplicationTaskCompletionSource.SetResult(true);
         }
         }
 
 
         public static void Restart()
         public static void Restart()
         {
         {
             DisposeAppHost();
             DisposeAppHost();
 
 
-            if (_isRunningAsService)
-            {
-                RestartWindowsService();
-            }
-            else
-            {
-                //_logger.Info("Hiding server notify icon");
-                //_serverNotifyIcon.Visible = false;
+            // todo: start new instance
 
 
-                _logger.Info("Starting new instance");
-                //Application.Restart();
-                Process.Start(_appHost.ServerConfigurationManager.ApplicationPaths.ApplicationPath);
-
-                ShutdownWindowsApplication();
-            }
+            Shutdown();
         }
         }
 
 
         private static void DisposeAppHost()
         private static void DisposeAppHost()
@@ -402,31 +282,6 @@ namespace Emby.Server
             }
             }
         }
         }
 
 
-        private static void ShutdownWindowsApplication()
-        {
-            //_logger.Info("Calling Application.Exit");
-            //Application.Exit();
-
-            _logger.Info("Calling Environment.Exit");
-            Environment.Exit(0);
-
-            _logger.Info("Calling ApplicationTaskCompletionSource.SetResult");
-            ApplicationTaskCompletionSource.SetResult(true);
-        }
-
-        private static void ShutdownWindowsService()
-        {
-        }
-
-        private static void RestartWindowsService()
-        {
-        }
-
-        private static bool CanRestartWindowsService()
-        {
-            return false;
-        }
-
         /// <summary>
         /// <summary>
         /// Sets the error mode.
         /// Sets the error mode.
         /// </summary>
         /// </summary>

+ 4 - 4
src/Emby.Server/project.json

@@ -12,10 +12,10 @@
       "version": "1.0.1"
       "version": "1.0.1"
     },
     },
     "Mono.Nat": "1.0.0-*",
     "Mono.Nat": "1.0.0-*",
-	"Microsoft.Win32.Registry": "4.0.0",
-	"System.Runtime.Extensions": "4.1.0",
-	"System.Diagnostics.Process": "4.1.0",
-	"Microsoft.Data.SQLite": "1.0.0"
+    "Microsoft.Win32.Registry": "4.0.0",
+    "System.Runtime.Extensions": "4.1.0",
+    "System.Diagnostics.Process": "4.1.0",
+    "Microsoft.Data.SQLite": "1.1.0-preview1-final"
   },
   },
 
 
   "frameworks": {
   "frameworks": {