Browse Source

Removed System.Windows.Forms dependancy from Common. Almost done removing NLog dependancy.

LukePulverenti 12 năm trước cách đây
mục cha
commit
fdafa59683
88 tập tin đã thay đổi với 1024 bổ sung766 xóa
  1. 2 2
      MediaBrowser.Api/HttpHandlers/PlaybackCheckInHandler.cs
  2. 4 4
      MediaBrowser.Api/LibraryService.cs
  3. 2 2
      MediaBrowser.Api/Streaming/BaseHlsPlaylistHandler.cs
  4. 1 1
      MediaBrowser.Api/Streaming/BaseProgressiveStreamingHandler.cs
  5. 7 7
      MediaBrowser.Api/Streaming/BaseStreamingHandler.cs
  6. 2 1
      MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
  7. 3 1
      MediaBrowser.Api/UserLibrary/ItemsService.cs
  8. 9 3
      MediaBrowser.Api/UserLibrary/UserLibraryService.cs
  9. 5 3
      MediaBrowser.Api/UserService.cs
  10. 2 3
      MediaBrowser.Common/IO/FileSystem.cs
  11. 20 62
      MediaBrowser.Common/Kernel/BaseKernel.cs
  12. 2 3
      MediaBrowser.Common/Kernel/BasePeriodicWebSocketListener.cs
  13. 19 0
      MediaBrowser.Common/Kernel/IApplicationHost.cs
  14. 1 8
      MediaBrowser.Common/Kernel/IKernel.cs
  15. 0 20
      MediaBrowser.Common/Logging/LogManager.cs
  16. 2 16
      MediaBrowser.Common/MediaBrowser.Common.csproj
  17. 0 1
      MediaBrowser.Common/Net/AlchemyWebSocket.cs
  18. 6 6
      MediaBrowser.Common/Net/BaseRestService.cs
  19. 5 22
      MediaBrowser.Common/Net/Handlers/BaseHandler.cs
  20. 2 2
      MediaBrowser.Common/Net/HttpServer.cs
  21. 1 2
      MediaBrowser.Common/Net/WebSocketConnection.cs
  22. 0 1
      MediaBrowser.Common/Plugins/BasePlugin.cs
  23. 3 3
      MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs
  24. 3 1
      MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs
  25. 0 1
      MediaBrowser.Common/ScheduledTasks/Tasks/SystemUpdateTask.cs
  26. 1 2
      MediaBrowser.Common/Serialization/XmlSerializer.cs
  27. 0 412
      MediaBrowser.Common/UI/BaseApplication.cs
  28. 1 2
      MediaBrowser.Controller/Drawing/ImageHeader.cs
  29. 15 2
      MediaBrowser.Controller/Drawing/ImageManager.cs
  30. 2 3
      MediaBrowser.Controller/Entities/BaseItem.cs
  31. 0 1
      MediaBrowser.Controller/Entities/CollectionFolder.cs
  32. 1 2
      MediaBrowser.Controller/Entities/Folder.cs
  33. 0 1
      MediaBrowser.Controller/Entities/Movies/Movie.cs
  34. 0 1
      MediaBrowser.Controller/Entities/User.cs
  35. 0 1
      MediaBrowser.Controller/IO/DirectoryWatchers.cs
  36. 0 1
      MediaBrowser.Controller/IO/FileData.cs
  37. 17 3
      MediaBrowser.Controller/Kernel.cs
  38. 20 16
      MediaBrowser.Controller/Library/DtoBuilder.cs
  39. 2 3
      MediaBrowser.Controller/Library/Profiler.cs
  40. 1 1
      MediaBrowser.Controller/Library/UserManager.cs
  41. 1 2
      MediaBrowser.Controller/Localization/LocalizedStrings.cs
  42. 3 2
      MediaBrowser.Controller/Localization/Ratings.cs
  43. 1 1
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  44. 3 22
      MediaBrowser.Controller/Providers/BaseImageEnhancer.cs
  45. 1 3
      MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
  46. 0 1
      MediaBrowser.Controller/Providers/MediaInfo/FFProbeAudioInfoProvider.cs
  47. 1 2
      MediaBrowser.Controller/Providers/TV/RemoteSeasonProvider.cs
  48. 2 3
      MediaBrowser.Controller/Resolvers/TV/TVUtils.cs
  49. BIN
      MediaBrowser.Installer/MediaBrowser.Installer_TemporaryKey.pfx
  50. 1 1
      MediaBrowser.Logging.NLog/LogHelper.cs
  51. 70 0
      MediaBrowser.Logging.NLog/MediaBrowser.Logging.NLog.csproj
  52. 2 2
      MediaBrowser.Logging.NLog/NLogger.cs
  53. 50 0
      MediaBrowser.Logging.NLog/NlogManager.cs
  54. 36 0
      MediaBrowser.Logging.NLog/Properties/AssemblyInfo.cs
  55. 4 0
      MediaBrowser.Logging.NLog/packages.config
  56. 8 2
      MediaBrowser.Plugins.MpcHc/MpcHcMediaPlayer.cs
  57. 7 1
      MediaBrowser.Plugins.Tmt5/Tmt5MediaPlayer.cs
  58. 0 1
      MediaBrowser.Server.Sqlite/SQLiteRepository.cs
  59. 6 3
      MediaBrowser.Server.Uninstall/MediaBrowser.Server.Uninstall.csproj
  60. 7 8
      MediaBrowser.ServerApplication/App.xaml
  61. 300 26
      MediaBrowser.ServerApplication/App.xaml.cs
  62. 1 2
      MediaBrowser.ServerApplication/Controls/ItemUpdateNotification.xaml.cs
  63. 1 2
      MediaBrowser.ServerApplication/Controls/MultiItemUpdateNotification.xaml.cs
  64. 1 1
      MediaBrowser.ServerApplication/Logging/LogWindow.xaml
  65. 1 1
      MediaBrowser.ServerApplication/Logging/LogWindow.xaml.cs
  66. 1 1
      MediaBrowser.ServerApplication/Logging/WindowTraceListener.cs
  67. 2 2
      MediaBrowser.ServerApplication/MainWindow.xaml.cs
  68. 18 0
      MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
  69. BIN
      MediaBrowser.ServerApplication/MediaBrowser.ServerApplication_TemporaryKey.pfx
  70. 1 0
      MediaBrowser.ServerApplication/packages.config
  71. 6 3
      MediaBrowser.UI.Uninstall/MediaBrowser.UI.Uninstall.csproj
  72. 12 0
      MediaBrowser.UI.sln
  73. 3 4
      MediaBrowser.UI/App.xaml
  74. 250 17
      MediaBrowser.UI/App.xaml.cs
  75. 3 10
      MediaBrowser.UI/Controller/UIKernel.cs
  76. 1 1
      MediaBrowser.UI/ImageViewerWindow.xaml.cs
  77. 0 2
      MediaBrowser.UI/MainWindow.xaml.cs
  78. 5 0
      MediaBrowser.UI/MediaBrowser.UI.csproj
  79. BIN
      MediaBrowser.UI/MediaBrowser.UI_TemporaryKey.pfx
  80. 2 3
      MediaBrowser.UI/Playback/BaseMediaPlayer.cs
  81. 6 2
      MediaBrowser.UI/Playback/ExternalPlayer/BaseExternalPlayer.cs
  82. 7 0
      MediaBrowser.UI/Playback/ExternalPlayer/GenericExternalPlayer.cs
  83. 5 0
      MediaBrowser.UI/Playback/InternalPlayer/BaseInternalMediaPlayer.cs
  84. 9 3
      MediaBrowser.UI/Playback/NVlc/InternalMediaPlayerNVlc.cs
  85. 1 2
      MediaBrowser.UI/ViewModels/DtoBaseItemViewModel.cs
  86. 1 1
      MediaBrowser.WebDashboard/Api/DashboardInfoWebSocketListener.cs
  87. 7 3
      MediaBrowser.WebDashboard/Api/DashboardService.cs
  88. 16 0
      MediaBrowser.sln

+ 2 - 2
MediaBrowser.Api/HttpHandlers/PlaybackCheckInHandler.cs

@@ -66,10 +66,10 @@ namespace MediaBrowser.Api.HttpHandlers
                     await Kernel.UserDataManager.OnPlaybackStopped(user, item, positionTicks, clientType, device).ConfigureAwait(false);
                 }
             }
-
+             
             var data = item.GetUserData(user, true);
 
-            return DtoBuilder.GetDtoUserItemData(data);
+            return new DtoBuilder(null).GetDtoUserItemData(data);
         }
 
         /// <summary>

+ 4 - 4
MediaBrowser.Api/LibraryService.cs

@@ -128,7 +128,7 @@ namespace MediaBrowser.Api
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
             
-            var result = DtoBuilder.GetDtoBaseItem(item, fields.ToList()).Result;
+            var result = new DtoBuilder(Logger).GetDtoBaseItem(item, fields.ToList()).Result;
 
             return ToOptimizedResult(result);
         }
@@ -147,7 +147,7 @@ namespace MediaBrowser.Api
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
 
-            var result = DtoBuilder.GetDtoBaseItem(item, fields.ToList()).Result;
+            var result = new DtoBuilder(Logger).GetDtoBaseItem(item, fields.ToList()).Result;
 
             return ToOptimizedResult(result);
         }
@@ -166,7 +166,7 @@ namespace MediaBrowser.Api
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
 
-            var result = DtoBuilder.GetDtoBaseItem(item, fields.ToList()).Result;
+            var result = new DtoBuilder(Logger).GetDtoBaseItem(item, fields.ToList()).Result;
 
             return ToOptimizedResult(result);
         }
@@ -185,7 +185,7 @@ namespace MediaBrowser.Api
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
 
-            var result = DtoBuilder.GetDtoBaseItem(item, fields.ToList()).Result;
+            var result = new DtoBuilder(Logger).GetDtoBaseItem(item, fields.ToList()).Result;
 
             return ToOptimizedResult(result);
         }

+ 2 - 2
MediaBrowser.Api/Streaming/BaseHlsPlaylistHandler.cs

@@ -208,12 +208,12 @@ namespace MediaBrowser.Api.Streaming
             {
                 try
                 {
-                    Logger.Info("Deleting HLS file {0}", file);
+                    //Logger.Info("Deleting HLS file {0}", file);
                     File.Delete(file);
                 }
                 catch (IOException ex)
                 {
-                    Logger.ErrorException("Error deleting HLS file {0}", ex, file);
+                    //Logger.ErrorException("Error deleting HLS file {0}", ex, file);
                 }
             }
         }

+ 1 - 1
MediaBrowser.Api/Streaming/BaseProgressiveStreamingHandler.cs

@@ -94,7 +94,7 @@ namespace MediaBrowser.Api.Streaming
             }
             catch (Exception ex)
             {
-                Logger.ErrorException("Error streaming media", ex);
+                //Logger.ErrorException("Error streaming media", ex);
             }
             finally
             {

+ 7 - 7
MediaBrowser.Api/Streaming/BaseStreamingHandler.cs

@@ -889,7 +889,7 @@ namespace MediaBrowser.Api.Streaming
 
             Plugin.Instance.OnTranscodeBeginning(outputPath, TranscodingJobType, process);
 
-            Logger.Info(process.StartInfo.FileName + " " + process.StartInfo.Arguments);
+            //Logger.Info(process.StartInfo.FileName + " " + process.StartInfo.Arguments);
 
             var logFilePath = Path.Combine(Kernel.ApplicationPaths.LogDirectoryPath, "ffmpeg-" + Guid.NewGuid() + ".txt");
 
@@ -904,7 +904,7 @@ namespace MediaBrowser.Api.Streaming
             }
             catch (Win32Exception ex)
             {
-                Logger.ErrorException("Error starting ffmpeg", ex);
+                //Logger.ErrorException("Error starting ffmpeg", ex);
 
                 Plugin.Instance.OnTranscodeFailedToStart(outputPath, TranscodingJobType);
 
@@ -953,11 +953,11 @@ namespace MediaBrowser.Api.Streaming
             try
             {
                 exitCode = process.ExitCode;
-                Logger.Info("FFMpeg exited with code {0} for {1}", exitCode.Value, outputFilePath);
+                //Logger.Info("FFMpeg exited with code {0} for {1}", exitCode.Value, outputFilePath);
             }
             catch
             {
-                Logger.Info("FFMpeg exited with an error for {0}", outputFilePath);
+                //Logger.Info("FFMpeg exited with an error for {0}", outputFilePath);
             }
 
             process.Dispose();
@@ -966,7 +966,7 @@ namespace MediaBrowser.Api.Streaming
 
             if (!exitCode.HasValue || exitCode.Value != 0)
             {
-                Logger.Info("Deleting partial stream file(s) {0}", outputFilePath);
+                //Logger.Info("Deleting partial stream file(s) {0}", outputFilePath);
 
                 try
                 {
@@ -974,12 +974,12 @@ namespace MediaBrowser.Api.Streaming
                 }
                 catch (IOException ex)
                 {
-                    Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, outputFilePath);
+                    //Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, outputFilePath);
                 }
             }
             else
             {
-                Logger.Info("FFMpeg completed and exited normally for {0}", outputFilePath);
+                //Logger.Info("FFMpeg completed and exited normally for {0}", outputFilePath);
             }
         }
 

+ 2 - 1
MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs

@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
 using ServiceStack.ServiceHost;
 using System;
 using System.Collections.Generic;
@@ -114,7 +115,7 @@ namespace MediaBrowser.Api.UserLibrary
                 return null;
             }
 
-            var dto = await DtoBuilder.GetDtoBaseItem(item, user, fields).ConfigureAwait(false);
+            var dto = await new DtoBuilder(Logger).GetDtoBaseItem(item, user, fields).ConfigureAwait(false);
 
             dto.ChildCount = stub.Item2();
 

+ 3 - 1
MediaBrowser.Api/UserLibrary/ItemsService.cs

@@ -191,7 +191,9 @@ namespace MediaBrowser.Api.UserLibrary
 
             var fields = GetItemFields(request).ToList();
 
-            var returnItems = await Task.WhenAll(pagedItems.Select(i => DtoBuilder.GetDtoBaseItem(i, user, fields))).ConfigureAwait(false);
+            var dtoBuilder = new DtoBuilder(Logger);
+
+            var returnItems = await Task.WhenAll(pagedItems.Select(i => dtoBuilder.GetDtoBaseItem(i, user, fields))).ConfigureAwait(false);
 
             return new ItemsResult
             {

+ 9 - 3
MediaBrowser.Api/UserLibrary/UserLibraryService.cs

@@ -268,7 +268,9 @@ namespace MediaBrowser.Api.UserLibrary
 
             var movie = (Movie)item;
 
-            var items = movie.SpecialFeatures.Select(i => DtoBuilder.GetDtoBaseItem(item, user, fields)).AsParallel().Select(t => t.Result).ToList();
+            var dtoBuilder = new DtoBuilder(Logger);
+
+            var items = movie.SpecialFeatures.Select(i => dtoBuilder.GetDtoBaseItem(item, user, fields)).AsParallel().Select(t => t.Result).ToList();
 
             return ToOptimizedResult(items);
         }
@@ -284,7 +286,9 @@ namespace MediaBrowser.Api.UserLibrary
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
 
-            var items = item.LocalTrailers.Select(i => DtoBuilder.GetDtoBaseItem(item, user, fields)).AsParallel().Select(t => t.Result).ToList();
+            var dtoBuilder = new DtoBuilder(Logger);
+
+            var items = item.LocalTrailers.Select(i => dtoBuilder.GetDtoBaseItem(item, user, fields)).AsParallel().Select(t => t.Result).ToList();
 
             return ToOptimizedResult(items);
         }
@@ -305,7 +309,9 @@ namespace MediaBrowser.Api.UserLibrary
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
 
-            var result = DtoBuilder.GetDtoBaseItem(item, user, fields).Result;
+            var dtoBuilder = new DtoBuilder(Logger);
+
+            var result = dtoBuilder.GetDtoBaseItem(item, user, fields).Result;
 
             return ToOptimizedResult(result);
         }

+ 5 - 3
MediaBrowser.Api/UserService.cs

@@ -146,7 +146,9 @@ namespace MediaBrowser.Api
         {
             var kernel = (Kernel)Kernel;
 
-            var result = kernel.Users.OrderBy(u => u.Name).Select(DtoBuilder.GetDtoUser).ToList();
+            var dtoBuilder = new DtoBuilder(Logger);
+
+            var result = kernel.Users.OrderBy(u => u.Name).Select(dtoBuilder.GetDtoUser).ToList();
 
             return ToOptimizedResult(result);
         }
@@ -167,7 +169,7 @@ namespace MediaBrowser.Api
                 throw new ResourceNotFoundException("User not found");
             }
 
-            var result = DtoBuilder.GetDtoUser(user);
+            var result = new DtoBuilder(Logger).GetDtoUser(user);
 
             return ToOptimizedResult(result);
         }
@@ -289,7 +291,7 @@ namespace MediaBrowser.Api
 
             var newUser = kernel.UserManager.CreateUser(dtoUser.Name).Result;
 
-            var result = DtoBuilder.GetDtoUser(newUser);
+            var result = new DtoBuilder(Logger).GetDtoUser(newUser);
 
             return ToOptimizedResult(result);
         }

+ 2 - 3
MediaBrowser.Common/IO/FileSystem.cs

@@ -1,8 +1,7 @@
-using System.Collections.Specialized;
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Common.Win32;
+using MediaBrowser.Common.Win32;
 using System;
 using System.Collections.Generic;
+using System.Collections.Specialized;
 using System.IO;
 using System.Runtime.InteropServices;
 using System.Text;

+ 20 - 62
MediaBrowser.Common/Kernel/BaseKernel.cs

@@ -9,9 +9,6 @@ using MediaBrowser.Common.Serialization;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.System;
-using NLog;
-using NLog.Config;
-using NLog.Targets;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel.Composition;
@@ -40,11 +37,6 @@ namespace MediaBrowser.Common.Kernel
         /// </summary>
         public event EventHandler HasPendingRestartChanged;
 
-        /// <summary>
-        /// Notifiies the containing application that a restart has been requested
-        /// </summary>
-        public event EventHandler ApplicationRestartRequested;
-
         #region ConfigurationUpdated Event
         /// <summary>
         /// Occurs when [configuration updated].
@@ -341,6 +333,12 @@ namespace MediaBrowser.Common.Kernel
         /// <value>The logger.</value>
         protected ILogger Logger { get; private set; }
 
+        /// <summary>
+        /// Gets or sets the application host.
+        /// </summary>
+        /// <value>The application host.</value>
+        protected IApplicationHost ApplicationHost { get; private set; }
+
         /// <summary>
         /// Gets the assemblies.
         /// </summary>
@@ -350,10 +348,17 @@ namespace MediaBrowser.Common.Kernel
         /// <summary>
         /// Initializes a new instance of the <see cref="BaseKernel{TApplicationPathsType}" /> class.
         /// </summary>
+        /// <param name="appHost">The app host.</param>
         /// <param name="isoManager">The iso manager.</param>
         /// <param name="logger">The logger.</param>
-        protected BaseKernel(IIsoManager isoManager, ILogger logger)
+        /// <exception cref="System.ArgumentNullException">isoManager</exception>
+        protected BaseKernel(IApplicationHost appHost, IIsoManager isoManager, ILogger logger)
         {
+            if (appHost == null)
+            {
+                throw new ArgumentNullException("appHost");
+            }
+            
             if (isoManager == null)
             {
                 throw new ArgumentNullException("isoManager");
@@ -363,7 +368,8 @@ namespace MediaBrowser.Common.Kernel
             {
                 throw new ArgumentNullException("logger");
             }
-            
+
+            ApplicationHost = appHost;
             IsoManager = isoManager;
             Logger = logger;
         }
@@ -440,42 +446,11 @@ namespace MediaBrowser.Common.Kernel
         /// </summary>
         public void ReloadLogger()
         {
-            DisposeLogger();
-
-            LogFilePath = Path.Combine(ApplicationPaths.LogDirectoryPath, KernelContext + "-" + DateTime.Now.Ticks + ".log");
-
-            var logFile = new FileTarget();
-
-            logFile.FileName = LogFilePath;
-            logFile.Layout = "${longdate}, ${level}, ${logger}, ${message}";
-
-            AddLogTarget(logFile, "ApplicationLogFile");
-
+            ApplicationHost.ReloadLogger();
+            
             OnLoggerLoaded();
         }
 
-        /// <summary>
-        /// Adds the log target.
-        /// </summary>
-        /// <param name="target">The target.</param>
-        /// <param name="name">The name.</param>
-        private void AddLogTarget(Target target, string name)
-        {
-            var config = LogManager.Configuration;
-
-            config.RemoveTarget(name);
-
-            target.Name = name;
-            config.AddTarget(name, target);
-
-            var level = Configuration.EnableDebugLevelLogging ? LogLevel.Debug : LogLevel.Info;
-
-            var rule = new LoggingRule("*", level, target);
-            config.LoggingRules.Add(rule);
-
-            LogManager.Configuration = config;
-        }
-
         /// <summary>
         /// Uses MEF to locate plugins
         /// Subclasses can use this to locate types within plugins
@@ -588,7 +563,7 @@ namespace MediaBrowser.Common.Kernel
 
                 foreach (var task in ScheduledTasks)
                 {
-                    task.Initialize(this);
+                    task.Initialize(this, Logger);
                 }
 
                 // Start-up each plugin
@@ -707,23 +682,6 @@ namespace MediaBrowser.Common.Kernel
             }
         }
 
-        /// <summary>
-        /// Disposes all logger resources
-        /// </summary>
-        private void DisposeLogger()
-        {
-            // Dispose all current loggers
-            var listeners = Trace.Listeners.OfType<TraceListener>().ToList();
-
-            Trace.Listeners.Clear();
-
-            foreach (var listener in listeners)
-            {
-                listener.Dispose();
-            }
-
-        }
-
         /// <summary>
         /// Gets the current application version
         /// </summary>
@@ -759,7 +717,7 @@ namespace MediaBrowser.Common.Kernel
         {
             Logger.Info("Restarting the application");
 
-            EventHelper.QueueEventIfNotNull(ApplicationRestartRequested, this, EventArgs.Empty, Logger);
+            ApplicationHost.Restart();
         }
 
         /// <summary>

+ 2 - 3
MediaBrowser.Common/Kernel/BasePeriodicWebSocketListener.cs

@@ -1,12 +1,11 @@
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Net.WebSockets;
 using System.Threading;
 using System.Threading.Tasks;
-using MediaBrowser.Model.Logging;
 
 namespace MediaBrowser.Common.Kernel
 {

+ 19 - 0
MediaBrowser.Common/Kernel/IApplicationHost.cs

@@ -0,0 +1,19 @@
+
+namespace MediaBrowser.Common.Kernel
+{
+    /// <summary>
+    /// An interface to be implemented by the applications hosting a kernel
+    /// </summary>
+    public interface IApplicationHost
+    {
+        /// <summary>
+        /// Restarts this instance.
+        /// </summary>
+        void Restart();
+
+        /// <summary>
+        /// Reloads the logger.
+        /// </summary>
+        void ReloadLogger();
+    }
+}

+ 1 - 8
MediaBrowser.Common/Kernel/IKernel.cs

@@ -1,6 +1,4 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Net.Handlers;
+using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Plugins;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Common.Serialization;
@@ -18,11 +16,6 @@ namespace MediaBrowser.Common.Kernel
     /// </summary>
     public interface IKernel
     {
-        /// <summary>
-        /// Occurs when [application restart requested].
-        /// </summary>
-        event EventHandler ApplicationRestartRequested;
-
         /// <summary>
         /// Gets the application paths.
         /// </summary>

+ 0 - 20
MediaBrowser.Common/Logging/LogManager.cs

@@ -1,20 +0,0 @@
-using MediaBrowser.Model.Logging;
-
-namespace MediaBrowser.Common.Logging
-{
-    /// <summary>
-    /// Class LogManager
-    /// </summary>
-    public static class LogManager
-    {
-        /// <summary>
-        /// Gets the logger.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <returns>ILogger.</returns>
-        public static ILogger GetLogger(string name)
-        {
-            return new NLogger(name);
-        }
-    }
-}

+ 2 - 16
MediaBrowser.Common/MediaBrowser.Common.csproj

@@ -114,8 +114,6 @@
     <Reference Include="System.Runtime.Remoting" />
     <Reference Include="System.Runtime.Serialization" />
     <Reference Include="System.Web" />
-    <Reference Include="System.Windows.Forms" />
-    <Reference Include="System.Xaml" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Data" />
@@ -142,16 +140,10 @@
     <Compile Include="Kernel\BaseManager.cs" />
     <Compile Include="Kernel\BasePeriodicWebSocketListener.cs" />
     <Compile Include="Kernel\BaseWebSocketListener.cs" />
+    <Compile Include="Kernel\IApplicationHost.cs" />
     <Compile Include="Kernel\IKernel.cs" />
     <Compile Include="Kernel\TcpManager.cs" />
     <Compile Include="Localization\LocalizedStringData.cs" />
-    <Compile Include="Logging\LogHelper.cs" />
-    <Compile Include="Logging\LogManager.cs" />
-    <Compile Include="Logging\LogWindow.xaml.cs">
-      <DependentUpon>LogWindow.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="Logging\NLogger.cs" />
-    <Compile Include="Logging\WindowTraceListener.cs" />
     <Compile Include="Mef\MefUtils.cs" />
     <Compile Include="Net\AlchemyWebSocket.cs" />
     <Compile Include="Net\BaseRestService.cs" />
@@ -201,7 +193,6 @@
     <Compile Include="ScheduledTasks\IntervalTrigger.cs" />
     <Compile Include="ScheduledTasks\IScheduledTask.cs" />
     <Compile Include="ScheduledTasks\WeeklyTrigger.cs" />
-    <Compile Include="UI\BaseApplication.cs" />
     <Compile Include="Updates\ApplicationUpdateCheck.cs" />
     <Compile Include="Updates\ApplicationUpdater.cs" />
     <Compile Include="Updates\ClickOnceHelper.cs" />
@@ -228,12 +219,6 @@
   <ItemGroup>
     <Resource Include="Resources\Images\Icon.ico" />
   </ItemGroup>
-  <ItemGroup>
-    <Page Include="Logging\LogWindow.xaml">
-      <SubType>Designer</SubType>
-      <Generator>MSBuild:Compile</Generator>
-    </Page>
-  </ItemGroup>
   <ItemGroup>
     <Resource Include="README.txt" />
     <Content Include="swagger-ui\css\screen.css" />
@@ -251,6 +236,7 @@
     <Content Include="swagger-ui\swagger-ui.js" />
     <Content Include="swagger-ui\swagger-ui.min.js" />
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 

+ 0 - 1
MediaBrowser.Common/Net/AlchemyWebSocket.cs

@@ -1,5 +1,4 @@
 using Alchemy.Classes;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Common.Serialization;
 using MediaBrowser.Model.Logging;
 using System;

+ 6 - 6
MediaBrowser.Common/Net/BaseRestService.cs

@@ -1,7 +1,6 @@
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Model.Logging;
 using ServiceStack.Common;
 using ServiceStack.Common.Web;
@@ -22,17 +21,18 @@ namespace MediaBrowser.Common.Net
     /// </summary>
     public class BaseRestService : Service, IRestfulService
     {
-        /// <summary>
-        /// The logger
-        /// </summary>
-        protected ILogger Logger = LogManager.GetLogger("RestService");
-
         /// <summary>
         /// Gets or sets the kernel.
         /// </summary>
         /// <value>The kernel.</value>
         public IKernel Kernel { get; set; }
 
+        /// <summary>
+        /// Gets or sets the logger.
+        /// </summary>
+        /// <value>The logger.</value>
+        public ILogger Logger { get; set; }
+        
         /// <summary>
         /// Gets a value indicating whether this instance is range request.
         /// </summary>

+ 5 - 22
MediaBrowser.Common/Net/Handlers/BaseHandler.cs

@@ -1,7 +1,5 @@
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Model.Logging;
 using System;
 using System.Collections;
 using System.Collections.Generic;
@@ -23,12 +21,6 @@ namespace MediaBrowser.Common.Net.Handlers
     public abstract class BaseHandler<TKernelType> : IHttpServerHandler
         where TKernelType : IKernel
     {
-        /// <summary>
-        /// Gets the logger.
-        /// </summary>
-        /// <value>The logger.</value>
-        protected ILogger Logger { get; private set; }
-
         /// <summary>
         /// Initializes the specified kernel.
         /// </summary>
@@ -36,7 +28,6 @@ namespace MediaBrowser.Common.Net.Handlers
         public void Initialize(IKernel kernel)
         {
             Kernel = (TKernelType)kernel;
-            Logger = SharedLogger.Logger;
         }
 
         /// <summary>
@@ -303,7 +294,7 @@ namespace MediaBrowser.Common.Net.Handlers
 
             response.ContentType = "text/plain";
 
-            Logger.ErrorException("Error processing request", ex);
+            //Logger.ErrorException("Error processing request", ex);
             
             if (!string.IsNullOrEmpty(ex.Message))
             {
@@ -321,7 +312,7 @@ namespace MediaBrowser.Common.Net.Handlers
             }
             catch (Exception ex1)
             {
-                Logger.ErrorException("Error dumping stack trace", ex1);
+                //Logger.ErrorException("Error dumping stack trace", ex1);
             }
         }
 
@@ -449,7 +440,7 @@ namespace MediaBrowser.Common.Net.Handlers
 
             if (Kernel.Configuration.EnableHttpLevelLogging)
             {
-                Logger.LogMultiline(msg, LogSeverity.Debug, log);
+                //Logger.LogMultiline(msg, LogSeverity.Debug, log);
             }
         }
 
@@ -604,7 +595,7 @@ namespace MediaBrowser.Common.Net.Handlers
                 }
                 catch (Exception ex)
                 {
-                    Logger.ErrorException("Error disposing compressed stream", ex);
+                    //Logger.ErrorException("Error disposing compressed stream", ex);
                 }
             }
 
@@ -615,7 +606,7 @@ namespace MediaBrowser.Common.Net.Handlers
             }
             catch (Exception ex)
             {
-                Logger.ErrorException("Error disposing response", ex);
+                //Logger.ErrorException("Error disposing response", ex);
             }
         }
 
@@ -750,14 +741,6 @@ namespace MediaBrowser.Common.Net.Handlers
         }
     }
 
-    internal static class SharedLogger
-    {
-        /// <summary>
-        /// The logger
-        /// </summary>
-        internal static ILogger Logger = LogManager.GetLogger("Http Handler");
-    }
-
     /// <summary>
     /// Class ResponseInfo
     /// </summary>

+ 2 - 2
MediaBrowser.Common/Net/HttpServer.cs

@@ -4,7 +4,6 @@ using MediaBrowser.Common.Kernel;
 using MediaBrowser.Model.Logging;
 using ServiceStack.Api.Swagger;
 using ServiceStack.Common.Web;
-using ServiceStack.Logging;
 using ServiceStack.Logging.NLogger;
 using ServiceStack.ServiceHost;
 using ServiceStack.ServiceInterface.Cors;
@@ -144,6 +143,7 @@ namespace MediaBrowser.Common.Net
             }
             
             container.Register(Kernel);
+            container.Register(_logger);
 
             foreach (var service in Kernel.RestServices)
             {
@@ -155,7 +155,7 @@ namespace MediaBrowser.Common.Net
 
             Serialization.JsonSerializer.Configure();
 
-            LogManager.LogFactory = new NLogFactory();
+            ServiceStack.Logging.LogManager.LogFactory = new NLogFactory();
         }
 
         /// <summary>

+ 1 - 2
MediaBrowser.Common/Net/WebSocketConnection.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Common.Serialization;
+using MediaBrowser.Common.Serialization;
 using MediaBrowser.Model.Logging;
 using System;
 using System.Net;

+ 0 - 1
MediaBrowser.Common/Plugins/BasePlugin.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Common.Serialization;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Plugins;

+ 3 - 3
MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs

@@ -1,6 +1,5 @@
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Common.Serialization;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Tasks;
@@ -301,9 +300,10 @@ namespace MediaBrowser.Common.ScheduledTasks
         /// Initializes the specified kernel.
         /// </summary>
         /// <param name="kernel">The kernel.</param>
-        public void Initialize(IKernel kernel)
+        /// <param name="logger">The logger.</param>
+        public void Initialize(IKernel kernel, ILogger logger)
         {
-            Logger = LogManager.GetLogger(GetType().Name);
+            Logger = logger;
             
             Kernel = (TKernelType)kernel;
             ReloadTriggerEvents();

+ 3 - 1
MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs

@@ -1,4 +1,5 @@
 using MediaBrowser.Common.Kernel;
+using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Tasks;
 using System;
 using System.Collections.Generic;
@@ -76,7 +77,8 @@ namespace MediaBrowser.Common.ScheduledTasks
         /// Initializes the specified kernel.
         /// </summary>
         /// <param name="kernel">The kernel.</param>
-        void Initialize(IKernel kernel);
+        /// <param name="logger">The logger.</param>
+        void Initialize(IKernel kernel, ILogger logger);
 
         /// <summary>
         /// Cancels if running.

+ 0 - 1
MediaBrowser.Common/ScheduledTasks/Tasks/SystemUpdateTask.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Common.Updates;
 using MediaBrowser.Model.Tasks;
 using System;

+ 1 - 2
MediaBrowser.Common/Serialization/XmlSerializer.cs

@@ -1,9 +1,8 @@
-using MediaBrowser.Common.Logging;
+using MediaBrowser.Model.Logging;
 using System;
 using System.IO;
 using System.Linq;
 using System.Xml;
-using MediaBrowser.Model.Logging;
 
 namespace MediaBrowser.Common.Serialization
 {

+ 0 - 412
MediaBrowser.Common/UI/BaseApplication.cs

@@ -1,412 +0,0 @@
-using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Updates;
-using MediaBrowser.Model.Logging;
-using Microsoft.Win32;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Deployment.Application;
-using System.Net.Cache;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-
-namespace MediaBrowser.Common.UI
-{
-    /// <summary>
-    /// Serves as a base Application class for both the UI and Server apps.
-    /// </summary>
-    public abstract class BaseApplication : Application, INotifyPropertyChanged
-    {
-        /// <summary>
-        /// The single instance mutex
-        /// </summary>
-        private Mutex SingleInstanceMutex;
-        /// <summary>
-        /// Gets the name of the publisher.
-        /// </summary>
-        /// <value>The name of the publisher.</value>
-        protected abstract string PublisherName { get; }
-        /// <summary>
-        /// Gets the name of the suite.
-        /// </summary>
-        /// <value>The name of the suite.</value>
-        protected abstract string SuiteName { get; }
-        /// <summary>
-        /// Gets the name of the product.
-        /// </summary>
-        /// <value>The name of the product.</value>
-        protected abstract string ProductName { get; }
-        /// <summary>
-        /// Gets the name of the uninstaller file.
-        /// </summary>
-        /// <value>The name of the uninstaller file.</value>
-        protected abstract string UninstallerFileName { get; }
-
-        /// <summary>
-        /// Gets or sets a value indicating whether [last run at startup value].
-        /// </summary>
-        /// <value><c>null</c> if [last run at startup value] contains no value, <c>true</c> if [last run at startup value]; otherwise, <c>false</c>.</value>
-        private bool? LastRunAtStartupValue { get; set; }
-
-        /// <summary>
-        /// Gets or sets the kernel.
-        /// </summary>
-        /// <value>The kernel.</value>
-        protected IKernel Kernel { get; set; }
-
-        /// <summary>
-        /// Instantiates the kernel.
-        /// </summary>
-        /// <returns>IKernel.</returns>
-        protected abstract IKernel InstantiateKernel();
-        /// <summary>
-        /// Instantiates the main window.
-        /// </summary>
-        /// <returns>Window.</returns>
-        protected abstract Window InstantiateMainWindow();
-
-        /// <summary>
-        /// Occurs when [property changed].
-        /// </summary>
-        public event PropertyChangedEventHandler PropertyChanged;
-
-        /// <summary>
-        /// Gets or sets the logger.
-        /// </summary>
-        /// <value>The logger.</value>
-        protected ILogger Logger { get; set; }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="BaseApplication" /> class.
-        /// </summary>
-        /// <param name="logger">The logger.</param>
-        protected BaseApplication(ILogger logger)
-        {
-            Logger = logger;
-        }
-
-        /// <summary>
-        /// Called when [property changed].
-        /// </summary>
-        /// <param name="info">The info.</param>
-        public void OnPropertyChanged(String info)
-        {
-            if (PropertyChanged != null)
-            {
-                try
-                {
-                    PropertyChanged(this, new PropertyChangedEventArgs(info));
-                }
-                catch (Exception ex)
-                {
-                    Logger.ErrorException("Error in event handler", ex);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Raises the <see cref="E:System.Windows.Application.Startup" /> event.
-        /// </summary>
-        /// <param name="e">A <see cref="T:System.Windows.StartupEventArgs" /> that contains the event data.</param>
-        protected override void OnStartup(StartupEventArgs e)
-        {
-            bool createdNew;
-            SingleInstanceMutex = new Mutex(true, @"Local\" + GetType().Assembly.GetName().Name, out createdNew);
-            if (!createdNew)
-            {
-                SingleInstanceMutex = null;
-                Shutdown();
-                return;
-            }
-            
-            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
-            LoadKernel();
-
-            SystemEvents.SessionEnding += SystemEvents_SessionEnding;
-        }
-
-        /// <summary>
-        /// Handles the UnhandledException event of the CurrentDomain control.
-        /// </summary>
-        /// <param name="sender">The source of the event.</param>
-        /// <param name="e">The <see cref="UnhandledExceptionEventArgs" /> instance containing the event data.</param>
-        void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
-        {
-            var exception = (Exception) e.ExceptionObject;
-
-            Logger.ErrorException("UnhandledException", exception);
-
-            MessageBox.Show("Unhandled exception: " + exception.Message);
-        }
-
-        /// <summary>
-        /// Handles the SessionEnding event of the SystemEvents control.
-        /// </summary>
-        /// <param name="sender">The source of the event.</param>
-        /// <param name="e">The <see cref="SessionEndingEventArgs" /> instance containing the event data.</param>
-        void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
-        {
-            // Try to shut down gracefully
-            Shutdown();
-        }
-
-        /// <summary>
-        /// Loads the kernel.
-        /// </summary>
-        protected virtual async void LoadKernel()
-        {
-            Kernel = InstantiateKernel();
-
-            try
-            {
-                InstantiateMainWindow().Show();
-
-                var now = DateTime.UtcNow;
-
-                await Kernel.Init();
-
-                var done = (DateTime.UtcNow - now);
-                Logger.Info("Kernel.Init completed in {0}{1} minutes and {2} seconds.", done.Hours > 0 ? done.Hours + " Hours " : "", done.Minutes, done.Seconds);
-
-                await OnKernelLoaded();
-            }
-            catch (Exception ex)
-            {
-                Logger.ErrorException("Error launching application", ex);
-
-                MessageBox.Show("There was an error launching Media Browser: " + ex.Message);
-
-                // Shutdown the app with an error code
-                Shutdown(1);
-            }
-        }
-
-        /// <summary>
-        /// Called when [kernel loaded].
-        /// </summary>
-        /// <returns>Task.</returns>
-        protected virtual Task OnKernelLoaded()
-        {
-            return Task.Run(() =>
-            {
-                Kernel.ApplicationRestartRequested += Kernel_ApplicationRestartRequested;
-                Kernel.ConfigurationUpdated += Kernel_ConfigurationUpdated;
-
-                ConfigureClickOnceStartup();
-            });
-        }
-
-        /// <summary>
-        /// Handles the ConfigurationUpdated event of the Kernel control.
-        /// </summary>
-        /// <param name="sender">The source of the event.</param>
-        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
-        void Kernel_ConfigurationUpdated(object sender, EventArgs e)
-        {
-            if (!LastRunAtStartupValue.HasValue || LastRunAtStartupValue.Value != Kernel.Configuration.RunAtStartup)
-            {
-                ConfigureClickOnceStartup();
-            }
-        }
-
-        /// <summary>
-        /// Configures the click once startup.
-        /// </summary>
-        private void ConfigureClickOnceStartup()
-        {
-            if (!ApplicationDeployment.IsNetworkDeployed)
-            {
-                return;
-            }
-
-            try
-            {
-                var clickOnceHelper = new ClickOnceHelper(PublisherName, ProductName, SuiteName);
-
-                if (Kernel.Configuration.RunAtStartup)
-                {
-                    clickOnceHelper.UpdateUninstallParameters(UninstallerFileName);
-                    clickOnceHelper.AddShortcutToStartup();
-                }
-                else
-                {
-                    clickOnceHelper.RemoveShortcutFromStartup();
-                }
-
-                LastRunAtStartupValue = Kernel.Configuration.RunAtStartup;
-            }
-            catch (Exception ex)
-            {
-                Logger.ErrorException("Error configuring ClickOnce", ex);
-            }
-        }
-
-        /// <summary>
-        /// Handles the ApplicationRestartRequested event of the Kernel control.
-        /// </summary>
-        /// <param name="sender">The source of the event.</param>
-        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
-        void Kernel_ApplicationRestartRequested(object sender, EventArgs e)
-        {
-            Restart();
-        }
-
-        /// <summary>
-        /// Restarts this instance.
-        /// </summary>
-        public void Restart()
-        {
-            Dispatcher.Invoke(ReleaseMutex);
-
-            Kernel.Dispose();
-
-            System.Windows.Forms.Application.Restart();
-
-            Dispatcher.Invoke(Shutdown);
-        }
-
-        /// <summary>
-        /// Releases the mutex.
-        /// </summary>
-        private void ReleaseMutex()
-        {
-            if (SingleInstanceMutex == null)
-            {
-                return;
-            }
-
-            SingleInstanceMutex.ReleaseMutex();
-            SingleInstanceMutex.Close();
-            SingleInstanceMutex.Dispose();
-            SingleInstanceMutex = null;
-        }
-
-        /// <summary>
-        /// Raises the <see cref="E:System.Windows.Application.Exit" /> event.
-        /// </summary>
-        /// <param name="e">An <see cref="T:System.Windows.ExitEventArgs" /> that contains the event data.</param>
-        protected override void OnExit(ExitEventArgs e)
-        {
-            ReleaseMutex(); 
-            
-            base.OnExit(e);
-
-            Kernel.Dispose();
-        }
-
-        /// <summary>
-        /// Signals the external command line args.
-        /// </summary>
-        /// <param name="args">The args.</param>
-        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
-        public bool SignalExternalCommandLineArgs(IList<string> args)
-        {
-            OnSecondInstanceLaunched(args);
-
-            return true;
-        }
-
-        /// <summary>
-        /// Called when [second instance launched].
-        /// </summary>
-        /// <param name="args">The args.</param>
-        protected virtual void OnSecondInstanceLaunched(IList<string> args)
-        {
-            if (MainWindow.WindowState == WindowState.Minimized)
-            {
-                MainWindow.WindowState = WindowState.Maximized;
-            }
-        }
-
-        /// <summary>
-        /// Gets the image.
-        /// </summary>
-        /// <param name="uri">The URI.</param>
-        /// <returns>Image.</returns>
-        /// <exception cref="System.ArgumentNullException">uri</exception>
-        public Image GetImage(string uri)
-        {
-            if (string.IsNullOrEmpty(uri))
-            {
-                throw new ArgumentNullException("uri");
-            }
-
-            return GetImage(new Uri(uri));
-        }
-
-        /// <summary>
-        /// Gets the image.
-        /// </summary>
-        /// <param name="uri">The URI.</param>
-        /// <returns>Image.</returns>
-        /// <exception cref="System.ArgumentNullException">uri</exception>
-        public Image GetImage(Uri uri)
-        {
-            if (uri == null)
-            {
-                throw new ArgumentNullException("uri");
-            }
-
-            return new Image { Source = GetBitmapImage(uri) };
-        }
-
-        /// <summary>
-        /// Gets the bitmap image.
-        /// </summary>
-        /// <param name="uri">The URI.</param>
-        /// <returns>BitmapImage.</returns>
-        /// <exception cref="System.ArgumentNullException">uri</exception>
-        public BitmapImage GetBitmapImage(string uri)
-        {
-            if (string.IsNullOrEmpty(uri))
-            {
-                throw new ArgumentNullException("uri");
-            }
-
-            return GetBitmapImage(new Uri(uri));
-        }
-
-        /// <summary>
-        /// Gets the bitmap image.
-        /// </summary>
-        /// <param name="uri">The URI.</param>
-        /// <returns>BitmapImage.</returns>
-        /// <exception cref="System.ArgumentNullException">uri</exception>
-        public BitmapImage GetBitmapImage(Uri uri)
-        {
-            if (uri == null)
-            {
-                throw new ArgumentNullException("uri");
-            }
-
-            var bitmap = new BitmapImage
-            {
-                CreateOptions = BitmapCreateOptions.DelayCreation,
-                CacheOption = BitmapCacheOption.OnDemand,
-                UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.CacheIfAvailable)
-            };
-
-            bitmap.BeginInit();
-            bitmap.UriSource = uri;
-            bitmap.EndInit();
-
-            RenderOptions.SetBitmapScalingMode(bitmap, BitmapScalingMode.Fant);
-            return bitmap;
-        }
-    }
-
-    /// <summary>
-    /// Interface IApplication
-    /// </summary>
-    public interface IApplication
-    {
-        /// <summary>
-        /// Initializes the component.
-        /// </summary>
-        void InitializeComponent();
-    }
-}

+ 1 - 2
MediaBrowser.Controller/Drawing/ImageHeader.cs

@@ -1,10 +1,9 @@
-using MediaBrowser.Common.Logging;
+using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Generic;
 using System.Drawing;
 using System.IO;
 using System.Linq;
-using MediaBrowser.Model.Logging;
 
 namespace MediaBrowser.Controller.Drawing
 {

+ 15 - 2
MediaBrowser.Controller/Drawing/ImageManager.cs

@@ -6,6 +6,7 @@ using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Drawing;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
@@ -15,7 +16,6 @@ using System.Drawing.Imaging;
 using System.IO;
 using System.Linq;
 using System.Threading.Tasks;
-using MediaBrowser.Model.Logging;
 
 namespace MediaBrowser.Controller.Drawing
 {
@@ -581,7 +581,20 @@ namespace MediaBrowser.Controller.Drawing
             // Run the enhancers sequentially in order of priority
             foreach (var enhancer in imageEnhancers)
             {
-                result = await enhancer.EnhanceImageAsync(item, result, imageType, imageIndex).ConfigureAwait(false);
+                var typeName = enhancer.GetType().Name;
+
+                _logger.Debug("Running {0} for {1}", typeName, item.Path ?? item.Name ?? "--Unknown--");
+
+                try
+                {
+                    result = await enhancer.EnhanceImageAsync(item, result, imageType, imageIndex).ConfigureAwait(false);
+                }
+                catch (Exception ex)
+                {
+                    _logger.ErrorException("{0} failed enhancing {1}", ex, typeName, item.Name);
+
+                    throw;
+                }
             }
 
             return result;

+ 2 - 3
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -1,6 +1,5 @@
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Common.Win32;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Library;
@@ -8,6 +7,7 @@ using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Resolvers;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Generic;
 using System.IO;
@@ -16,7 +16,6 @@ using System.Runtime.Serialization;
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
-using MediaBrowser.Model.Logging;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -97,7 +96,7 @@ namespace MediaBrowser.Controller.Entities
         /// <summary>
         /// The logger
         /// </summary>
-        protected static ILogger Logger = LogManager.GetLogger("BaseItem");
+        protected static internal ILogger Logger { get; internal set; }
 
         /// <summary>
         /// Returns a <see cref="System.String" /> that represents this instance.

+ 0 - 1
MediaBrowser.Controller/Entities/CollectionFolder.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Model.Tasks;
 using System;
 using System.Collections.Concurrent;

+ 1 - 2
MediaBrowser.Controller/Entities/Folder.cs

@@ -1,11 +1,11 @@
 using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Common.Win32;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Resolvers;
 using MediaBrowser.Controller.Sorting;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Tasks;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
@@ -14,7 +14,6 @@ using System.Linq;
 using System.Runtime.Serialization;
 using System.Threading;
 using System.Threading.Tasks;
-using MediaBrowser.Model.Tasks;
 using SortOrder = MediaBrowser.Controller.Sorting.SortOrder;
 
 namespace MediaBrowser.Controller.Entities

+ 0 - 1
MediaBrowser.Controller/Entities/Movies/Movie.cs

@@ -1,6 +1,5 @@
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Common.Win32;
 using MediaBrowser.Model.Entities;
 using System;

+ 0 - 1
MediaBrowser.Controller/Entities/User.cs

@@ -1,6 +1,5 @@
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Common.Serialization;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Tasks;

+ 0 - 1
MediaBrowser.Controller/IO/DirectoryWatchers.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.ScheduledTasks;

+ 0 - 1
MediaBrowser.Controller/IO/FileData.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Common.Win32;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Logging;

+ 17 - 3
MediaBrowser.Controller/Kernel.cs

@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.MediaInfo;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Playback;
@@ -312,12 +313,18 @@ namespace MediaBrowser.Controller
         /// </summary>
         /// <value>The bluray examiner.</value>
         private IBlurayExaminer BlurayExaminer { get; set; }
-        
+
         /// <summary>
         /// Creates a kernel based on a Data path, which is akin to our current programdata path
         /// </summary>
-        public Kernel(IIsoManager isoManager, IZipClient zipClient, IBlurayExaminer blurayExaminer, ILogger logger)
-            : base(isoManager, logger)
+        /// <param name="appHost">The app host.</param>
+        /// <param name="isoManager">The iso manager.</param>
+        /// <param name="zipClient">The zip client.</param>
+        /// <param name="blurayExaminer">The bluray examiner.</param>
+        /// <param name="logger">The logger.</param>
+        /// <exception cref="System.ArgumentNullException">isoManager</exception>
+        public Kernel(IApplicationHost appHost, IIsoManager isoManager, IZipClient zipClient, IBlurayExaminer blurayExaminer, ILogger logger)
+            : base(appHost, isoManager, logger)
         {
             if (isoManager == null)
             {
@@ -337,6 +344,13 @@ namespace MediaBrowser.Controller
             Instance = this;
             ZipClient = zipClient;
             BlurayExaminer = blurayExaminer;
+
+            // For now there's no real way to inject this properly
+            BaseItem.Logger = logger;
+            Ratings.Logger = logger;
+            LocalizedStrings.Logger = logger;
+            // For now, until this can become an interface
+            BaseMetadataProvider.Logger = logger;
         }
 
         /// <summary>

+ 20 - 16
MediaBrowser.Controller/Library/DtoBuilder.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Entities.TV;
@@ -18,14 +17,19 @@ namespace MediaBrowser.Controller.Library
     /// <summary>
     /// Generates DTO's from domain entities
     /// </summary>
-    public static class DtoBuilder
+    public class DtoBuilder
     {
         /// <summary>
         /// The index folder delimeter
         /// </summary>
         const string IndexFolderDelimeter = "-index-";
 
-        private static ILogger Logger = LogManager.GetLogger("DtoBuilder");
+        private ILogger Logger;
+
+        public DtoBuilder(ILogger logger)
+        {
+            Logger = logger;
+        }
 
         /// <summary>
         /// Gets the dto base item.
@@ -34,7 +38,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="fields">The fields.</param>
         /// <returns>Task{DtoBaseItem}.</returns>
         /// <exception cref="System.ArgumentNullException">item</exception>
-        public async static Task<BaseItemDto> GetDtoBaseItem(BaseItem item, List<ItemFields> fields)
+        public async Task<BaseItemDto> GetDtoBaseItem(BaseItem item, List<ItemFields> fields)
         {
             if (item == null)
             {
@@ -91,7 +95,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="fields">The fields.</param>
         /// <returns>Task{DtoBaseItem}.</returns>
         /// <exception cref="System.ArgumentNullException"></exception>
-        public async static Task<BaseItemDto> GetDtoBaseItem(BaseItem item, User user, List<ItemFields> fields)
+        public async Task<BaseItemDto> GetDtoBaseItem(BaseItem item, User user, List<ItemFields> fields)
         {
             if (item == null)
             {
@@ -153,7 +157,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="item">The item.</param>
         /// <param name="user">The user.</param>
         /// <param name="fields">The fields.</param>
-        private static void AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, List<ItemFields> fields)
+        private void AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, List<ItemFields> fields)
         {
             dto.IsNew = item.IsRecentlyAdded(user);
 
@@ -192,7 +196,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="dto">The dto.</param>
         /// <param name="item">The item.</param>
         /// <returns>Task.</returns>
-        private static async Task AttachPrimaryImageAspectRatio(BaseItemDto dto, BaseItem item)
+        private async Task AttachPrimaryImageAspectRatio(BaseItemDto dto, BaseItem item)
         {
             var path = item.PrimaryImagePath;
 
@@ -234,7 +238,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="dto">The dto.</param>
         /// <param name="item">The item.</param>
         /// <param name="fields">The fields.</param>
-        private static void AttachBasicFields(BaseItemDto dto, BaseItem item, List<ItemFields> fields)
+        private void AttachBasicFields(BaseItemDto dto, BaseItem item, List<ItemFields> fields)
         {
             if (fields.Contains(ItemFields.DateCreated))
             {
@@ -555,7 +559,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="dto">The dto.</param>
         /// <param name="item">The item.</param>
         /// <returns>Task.</returns>
-        private static async Task AttachPeople(BaseItemDto dto, BaseItem item)
+        private async Task AttachPeople(BaseItemDto dto, BaseItem item)
         {
             if (item.People == null)
             {
@@ -614,7 +618,7 @@ namespace MediaBrowser.Controller.Library
         /// </summary>
         /// <param name="item">The item.</param>
         /// <returns>BaseItem.</returns>
-        private static BaseItem GetParentBackdropItem(BaseItem item)
+        private BaseItem GetParentBackdropItem(BaseItem item)
         {
             var parent = item.Parent;
 
@@ -636,7 +640,7 @@ namespace MediaBrowser.Controller.Library
         /// </summary>
         /// <param name="item">The item.</param>
         /// <returns>BaseItem.</returns>
-        private static BaseItem GetParentLogoItem(BaseItem item)
+        private BaseItem GetParentLogoItem(BaseItem item)
         {
             var parent = item.Parent;
 
@@ -675,7 +679,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="data">The data.</param>
         /// <returns>DtoUserItemData.</returns>
         /// <exception cref="System.ArgumentNullException"></exception>
-        public static UserItemDataDto GetDtoUserItemData(UserItemData data)
+        public UserItemDataDto GetDtoUserItemData(UserItemData data)
         {
             if (data == null)
             {
@@ -699,7 +703,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="chapterInfo">The chapter info.</param>
         /// <param name="item">The item.</param>
         /// <returns>ChapterInfoDto.</returns>
-        private static ChapterInfoDto GetChapterInfoDto(ChapterInfo chapterInfo, BaseItem item)
+        private ChapterInfoDto GetChapterInfoDto(ChapterInfo chapterInfo, BaseItem item)
         {
             var dto = new ChapterInfoDto
             {
@@ -786,7 +790,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="user">The user.</param>
         /// <returns>DtoUser.</returns>
         /// <exception cref="System.ArgumentNullException">user</exception>
-        public static UserDto GetDtoUser(User user)
+        public UserDto GetDtoUser(User user)
         {
             if (user == null)
             {
@@ -924,7 +928,7 @@ namespace MediaBrowser.Controller.Library
         /// </summary>
         /// <param name="item">The item.</param>
         /// <returns>List{System.String}.</returns>
-        private static List<Guid> GetBackdropImageTags(BaseItem item)
+        private List<Guid> GetBackdropImageTags(BaseItem item)
         {
             if (item.BackdropImagePaths == null)
             {

+ 2 - 3
MediaBrowser.Controller/Library/Profiler.cs

@@ -1,7 +1,6 @@
-using System;
+using MediaBrowser.Model.Logging;
+using System;
 using System.Diagnostics;
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Model.Logging;
 
 namespace MediaBrowser.Controller.Library
 {

+ 1 - 1
MediaBrowser.Controller/Library/UserManager.cs

@@ -73,7 +73,7 @@ namespace MediaBrowser.Controller.Library
             EventHelper.QueueEventIfNotNull(UserUpdated, this, new GenericEventArgs<User> { Argument = user }, _logger);
 
             // Notify connected ui's
-            Kernel.TcpManager.SendWebSocketMessage("UserUpdated", DtoBuilder.GetDtoUser(user));
+            Kernel.TcpManager.SendWebSocketMessage("UserUpdated", new DtoBuilder(_logger).GetDtoUser(user));
         }
         #endregion
 

+ 1 - 2
MediaBrowser.Controller/Localization/LocalizedStrings.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.Localization;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Concurrent;
@@ -19,7 +18,7 @@ namespace MediaBrowser.Controller.Localization
         /// <summary>
         /// The logger
         /// </summary>
-        private static readonly ILogger Logger = LogManager.GetLogger("LocalizedStrings");
+        static internal ILogger Logger { get; set; }
         /// <summary>
         /// The base prefix
         /// </summary>

+ 3 - 2
MediaBrowser.Controller/Localization/Ratings.cs

@@ -1,8 +1,8 @@
 using MediaBrowser.Common.Extensions;
+using MediaBrowser.Model.Logging;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
-using MediaBrowser.Common.Logging;
 
 namespace MediaBrowser.Controller.Localization
 {
@@ -11,6 +11,7 @@ namespace MediaBrowser.Controller.Localization
     /// </summary>
     public static class Ratings
     {
+        static internal ILogger Logger { get; set; }
         /// <summary>
         /// The ratings def
         /// </summary>
@@ -40,7 +41,7 @@ namespace MediaBrowser.Controller.Localization
         public static Dictionary<string, int> Initialize(bool blockUnrated)
         {
             //build our ratings dictionary from the combined local one and us one
-            ratingsDef = new RatingsDefinition(Path.Combine(Kernel.Instance.ApplicationPaths.LocalizationPath, "Ratings-" + Kernel.Instance.Configuration.MetadataCountryCode + ".txt"), LogManager.GetLogger("RatingsDefinition"));
+            ratingsDef = new RatingsDefinition(Path.Combine(Kernel.Instance.ApplicationPaths.LocalizationPath, "Ratings-" + Kernel.Instance.Configuration.MetadataCountryCode + ".txt"), Logger);
             //global value of None
             var dict = new Dictionary<string, int> {{"None", -1}};
             foreach (var pair in ratingsDef.RatingsDict)

+ 1 - 1
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -130,8 +130,8 @@
     <Compile Include="Playback\IIntroProvider.cs" />
     <Compile Include="Plugins\BaseConfigurationPage.cs" />
     <Compile Include="Plugins\PluginSecurityManager.cs" />
-    <Compile Include="Providers\BaseImageEnhancer.cs" />
     <Compile Include="Providers\FanartBaseProvider.cs" />
+    <Compile Include="Providers\BaseImageEnhancer.cs" />
     <Compile Include="Providers\ImagesByNameProvider.cs" />
     <Compile Include="Providers\MediaInfo\BaseFFMpegImageProvider.cs" />
     <Compile Include="Providers\MediaInfo\BaseFFMpegProvider.cs" />

+ 3 - 22
MediaBrowser.Controller/Providers/BaseImageEnhancer.cs

@@ -1,8 +1,6 @@
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Model.Drawing;
 using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Logging;
 using System;
 using System.Drawing;
 using System.Threading.Tasks;
@@ -14,10 +12,6 @@ namespace MediaBrowser.Controller.Providers
     /// </summary>
     public abstract class BaseImageEnhancer : IDisposable
     {
-        /// <summary>
-        /// The logger
-        /// </summary>
-        private static readonly ILogger Logger = LogManager.GetLogger("ImageEnhancer");
         /// <summary>
         /// Return true only if the given image for the given item will be enhanced by this enhancer.
         /// </summary>
@@ -92,27 +86,14 @@ namespace MediaBrowser.Controller.Providers
         /// <param name="imageIndex">Index of the image.</param>
         /// <returns>Task{Image}.</returns>
         /// <exception cref="System.ArgumentNullException"></exception>
-        public async Task<Image> EnhanceImageAsync(BaseItem item, Image originalImage, ImageType imageType, int imageIndex)
+        public Task<Image> EnhanceImageAsync(BaseItem item, Image originalImage, ImageType imageType, int imageIndex)
         {
             if (item == null || originalImage == null)
             {
                 throw new ArgumentNullException();
             }
 
-            var typeName = GetType().Name;
-
-            Logger.Debug("Running {0} for {1}", typeName, item.Path ?? item.Name ?? "--Unknown--");
-
-            try
-            {
-                return await EnhanceImageAsyncInternal(item, originalImage, imageType, imageIndex).ConfigureAwait(false);
-            }
-            catch (Exception ex)
-            {
-                Logger.ErrorException("{0} failed enhancing {1}", ex, typeName, item.Name);
-
-                throw;
-            }
+            return EnhanceImageAsyncInternal(item, originalImage, imageType, imageIndex);
         }
     }
 }

+ 1 - 3
MediaBrowser.Controller/Providers/BaseMetadataProvider.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Model.Logging;
 using System;
@@ -17,7 +16,7 @@ namespace MediaBrowser.Controller.Providers
         /// Gets the logger.
         /// </summary>
         /// <value>The logger.</value>
-        protected ILogger Logger { get; private set; }
+        protected static internal ILogger Logger { get; internal set; }
 
         // Cache these since they will be used a lot
         /// <summary>
@@ -113,7 +112,6 @@ namespace MediaBrowser.Controller.Providers
         /// </summary>
         protected virtual void Initialize()
         {
-            Logger = LogManager.GetLogger(GetType().Name);
         }
 
         /// <summary>

+ 0 - 1
MediaBrowser.Controller/Providers/MediaInfo/FFProbeAudioInfoProvider.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.MediaInfo;

+ 1 - 2
MediaBrowser.Controller/Providers/TV/RemoteSeasonProvider.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Resolvers.TV;
 using MediaBrowser.Model.Entities;

+ 2 - 3
MediaBrowser.Controller/Resolvers/TV/TVUtils.cs

@@ -1,9 +1,8 @@
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Common.Win32;
+using MediaBrowser.Common.Win32;
 using System;
 using System.Collections.Generic;
-using System.Text.RegularExpressions;
 using System.Linq;
+using System.Text.RegularExpressions;
 
 namespace MediaBrowser.Controller.Resolvers.TV
 {

BIN
MediaBrowser.Installer/MediaBrowser.Installer_TemporaryKey.pfx


+ 1 - 1
MediaBrowser.Common/Logging/LogHelper.cs → MediaBrowser.Logging.NLog/LogHelper.cs

@@ -1,7 +1,7 @@
 using System;
 using System.Text;
 
-namespace MediaBrowser.Common.Logging
+namespace MediaBrowser.Logging.Nlog
 {
     /// <summary>
     /// Class LogHelper

+ 70 - 0
MediaBrowser.Logging.NLog/MediaBrowser.Logging.NLog.csproj

@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{67310740-0EC4-4DC2-9921-33DF38B20167}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>MediaBrowser.Logging.NLog</RootNamespace>
+    <AssemblyName>MediaBrowser.Logging.NLog</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
+    <RestorePackages>true</RestorePackages>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="NLog">
+      <HintPath>..\packages\NLog.2.0.0.2000\lib\net40\NLog.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="LogHelper.cs" />
+    <Compile Include="NLogger.cs" />
+    <Compile Include="NlogManager.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
+      <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
+      <Name>MediaBrowser.Model</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 2 - 2
MediaBrowser.Common/Logging/NLogger.cs → MediaBrowser.Logging.NLog/NLogger.cs

@@ -2,12 +2,12 @@
 using System;
 using System.Text;
 
-namespace MediaBrowser.Common.Logging
+namespace MediaBrowser.Logging.Nlog
 {
     /// <summary>
     /// Class NLogger
     /// </summary>
-    internal class NLogger : ILogger
+    public class NLogger : ILogger
     {
         /// <summary>
         /// The _logger

+ 50 - 0
MediaBrowser.Logging.NLog/NlogManager.cs

@@ -0,0 +1,50 @@
+using NLog;
+using NLog.Config;
+using NLog.Targets;
+
+namespace MediaBrowser.Logging.Nlog
+{
+    /// <summary>
+    /// Class NlogManager
+    /// </summary>
+    public static class NlogManager
+    {
+        /// <summary>
+        /// Adds the file target.
+        /// </summary>
+        /// <param name="path">The path.</param>
+        /// <param name="enableDebugLogging">if set to <c>true</c> [enable debug logging].</param>
+        public static void AddFileTarget(string path, bool enableDebugLogging)
+        {
+            var logFile = new FileTarget();
+
+            logFile.FileName = path;
+            logFile.Layout = "${longdate}, ${level}, ${logger}, ${message}";
+
+            AddLogTarget(logFile, "ApplicationLogFile", enableDebugLogging);
+        }
+
+        /// <summary>
+        /// Adds the log target.
+        /// </summary>
+        /// <param name="target">The target.</param>
+        /// <param name="name">The name.</param>
+        /// <param name="enableDebugLogging">if set to <c>true</c> [enable debug logging].</param>
+        private static void AddLogTarget(Target target, string name, bool enableDebugLogging)
+        {
+            var config = LogManager.Configuration;
+
+            config.RemoveTarget(name);
+
+            target.Name = name;
+            config.AddTarget(name, target);
+
+            var level = enableDebugLogging ? LogLevel.Debug : LogLevel.Info;
+
+            var rule = new LoggingRule("*", level, target);
+            config.LoggingRules.Add(rule);
+
+            LogManager.Configuration = config;
+        }
+    }
+}

+ 36 - 0
MediaBrowser.Logging.NLog/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MediaBrowser.Logging.NLog")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MediaBrowser.Logging.NLog")]
+[assembly: AssemblyCopyright("Copyright ©  2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("095763bf-68a9-4d89-ad01-d0e3c1f5c11f")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 4 - 0
MediaBrowser.Logging.NLog/packages.config

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="NLog" version="2.0.0.2000" targetFramework="net45" />
+</packages>

+ 8 - 2
MediaBrowser.Plugins.MpcHc/MpcHcMediaPlayer.cs

@@ -1,6 +1,6 @@
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
 using MediaBrowser.UI.Configuration;
 using MediaBrowser.UI.Controller;
 using MediaBrowser.UI.Playback;
@@ -32,6 +32,12 @@ namespace MediaBrowser.Plugins.MpcHc
         /// </summary>
         private SemaphoreSlim MpcHttpInterfaceResourcePool = new SemaphoreSlim(1, 1);
 
+        [ImportingConstructor]
+        public MpcHcMediaPlayer([Import("logger")] ILogger logger)
+            : base(logger)
+        {
+        }
+
         /// <summary>
         /// Gets or sets the HTTP interface cancellation token.
         /// </summary>

+ 7 - 1
MediaBrowser.Plugins.Tmt5/Tmt5MediaPlayer.cs

@@ -1,6 +1,6 @@
 using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Logging;
 using MediaBrowser.UI.Configuration;
 using MediaBrowser.UI.Playback;
 using MediaBrowser.UI.Playback.ExternalPlayer;
@@ -21,6 +21,12 @@ namespace MediaBrowser.Plugins.Tmt5
     [Export(typeof(BaseMediaPlayer))]
     public class Tmt5MediaPlayer : BaseExternalPlayer
     {
+        [ImportingConstructor]
+        public Tmt5MediaPlayer([Import("logger")] ILogger logger)
+            : base(logger)
+        {
+        }
+
         /// <summary>
         /// Gets the name.
         /// </summary>

+ 0 - 1
MediaBrowser.Server.Sqlite/SQLiteRepository.cs

@@ -1,4 +1,3 @@
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Concurrent;

+ 6 - 3
MediaBrowser.Server.Uninstall/MediaBrowser.Server.Uninstall.csproj

@@ -44,9 +44,6 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="..\MediaBrowser.Common\Updates\ClickOnceHelper.cs">
-      <Link>ClickOnceHelper.cs</Link>
-    </Compile>
     <Compile Include="Globals.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
@@ -54,6 +51,12 @@
   <ItemGroup>
     <None Include="App.config" />
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
+      <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
+      <Name>MediaBrowser.Common</Name>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

+ 7 - 8
MediaBrowser.ServerApplication/App.xaml

@@ -1,8 +1,7 @@
-<z:BaseApplication x:Class="MediaBrowser.ServerApplication.App"
-             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-             xmlns:z="clr-namespace:MediaBrowser.Common.UI;assembly=MediaBrowser.Common">
-    <Application.Resources>
-
-    </Application.Resources>
-</z:BaseApplication>
+<Application x:Class="MediaBrowser.ServerApplication.App"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+    <Application.Resources>
+
+    </Application.Resources>
+</Application>

+ 300 - 26
MediaBrowser.ServerApplication/App.xaml.cs

@@ -1,23 +1,31 @@
 using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Common.UI;
+using MediaBrowser.Common.Updates;
 using MediaBrowser.Controller;
 using MediaBrowser.IsoMounter;
+using MediaBrowser.Logging.Nlog;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Server.Uninstall;
 using MediaBrowser.ServerApplication.Implementations;
+using Microsoft.Win32;
 using System;
-using System.Collections.Generic;
+using System.Deployment.Application;
 using System.Diagnostics;
+using System.IO;
 using System.Linq;
+using System.Net.Cache;
+using System.Threading;
+using System.Threading.Tasks;
 using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
 
 namespace MediaBrowser.ServerApplication
 {
     /// <summary>
     /// Interaction logic for App.xaml
     /// </summary>
-    public partial class App : BaseApplication, IApplication
+    public partial class App : Application, IApplicationHost
     {
         /// <summary>
         /// Defines the entry point of the application.
@@ -25,8 +33,7 @@ namespace MediaBrowser.ServerApplication
         [STAThread]
         public static void Main()
         {
-            var application = new App(LogManager.GetLogger("App"));
-            application.InitializeComponent();
+            var application = new App(new NLogger("App"));
 
             application.Run();
         }
@@ -43,21 +50,45 @@ namespace MediaBrowser.ServerApplication
             }
         }
 
+        /// <summary>
+        /// The single instance mutex
+        /// </summary>
+        private Mutex SingleInstanceMutex;
+
+        /// <summary>
+        /// Gets or sets the kernel.
+        /// </summary>
+        /// <value>The kernel.</value>
+        protected IKernel Kernel { get; set; }
+
+        /// <summary>
+        /// Gets or sets the logger.
+        /// </summary>
+        /// <value>The logger.</value>
+        protected ILogger Logger { get; set; }
+
+        /// <summary>
+        /// Gets or sets the log file path.
+        /// </summary>
+        /// <value>The log file path.</value>
+        private string LogFilePath { get; set; }
+
         /// <summary>
         /// Initializes a new instance of the <see cref="App" /> class.
         /// </summary>
         /// <param name="logger">The logger.</param>
         public App(ILogger logger)
-            : base(logger)
         {
-            
+            Logger = logger;
+
+            InitializeComponent();
         }
 
         /// <summary>
         /// Gets the name of the product.
         /// </summary>
         /// <value>The name of the product.</value>
-        protected override string ProductName
+        protected string ProductName
         {
             get { return Globals.ProductName; }
         }
@@ -66,7 +97,7 @@ namespace MediaBrowser.ServerApplication
         /// Gets the name of the publisher.
         /// </summary>
         /// <value>The name of the publisher.</value>
-        protected override string PublisherName
+        protected string PublisherName
         {
             get { return Globals.PublisherName; }
         }
@@ -75,7 +106,7 @@ namespace MediaBrowser.ServerApplication
         /// Gets the name of the suite.
         /// </summary>
         /// <value>The name of the suite.</value>
-        protected override string SuiteName
+        protected string SuiteName
         {
             get { return Globals.SuiteName; }
         }
@@ -84,21 +115,180 @@ namespace MediaBrowser.ServerApplication
         /// Gets the name of the uninstaller file.
         /// </summary>
         /// <value>The name of the uninstaller file.</value>
-        protected override string UninstallerFileName
+        protected string UninstallerFileName
         {
             get { return "MediaBrowser.Server.Uninstall.exe"; }
         }
 
         /// <summary>
-        /// Called when [second instance launched].
+        /// Gets or sets a value indicating whether [last run at startup value].
         /// </summary>
-        /// <param name="args">The args.</param>
-        protected override void OnSecondInstanceLaunched(IList<string> args)
+        /// <value><c>null</c> if [last run at startup value] contains no value, <c>true</c> if [last run at startup value]; otherwise, <c>false</c>.</value>
+        private bool? LastRunAtStartupValue { get; set; }
+
+        /// <summary>
+        /// Raises the <see cref="E:System.Windows.Application.Startup" /> event.
+        /// </summary>
+        /// <param name="e">A <see cref="T:System.Windows.StartupEventArgs" /> that contains the event data.</param>
+        protected override void OnStartup(StartupEventArgs e)
         {
-            base.OnSecondInstanceLaunched(args);
+            bool createdNew;
+            SingleInstanceMutex = new Mutex(true, @"Local\" + GetType().Assembly.GetName().Name, out createdNew);
+            if (!createdNew)
+            {
+                SingleInstanceMutex = null;
+                Shutdown();
+                return;
+            }
 
-            OpenDashboard();
-            InitializeComponent();
+            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
+            LoadKernel();
+
+            SystemEvents.SessionEnding += SystemEvents_SessionEnding;
+        }
+
+        /// <summary>
+        /// Handles the UnhandledException event of the CurrentDomain control.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="UnhandledExceptionEventArgs" /> instance containing the event data.</param>
+        void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
+        {
+            var exception = (Exception)e.ExceptionObject;
+
+            Logger.ErrorException("UnhandledException", exception);
+
+            MessageBox.Show("Unhandled exception: " + exception.Message);
+        }
+
+        /// <summary>
+        /// Handles the SessionEnding event of the SystemEvents control.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="SessionEndingEventArgs" /> instance containing the event data.</param>
+        void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
+        {
+            // Try to shut down gracefully
+            Shutdown();
+        }
+
+        /// <summary>
+        /// Loads the kernel.
+        /// </summary>
+        protected async void LoadKernel()
+        {
+            Kernel = new Kernel(this, new PismoIsoManager(Logger), new DotNetZipClient(), new BdInfoExaminer(), Logger);
+
+            try
+            {
+                new MainWindow(Logger).Show();
+
+                var now = DateTime.UtcNow;
+
+                await Kernel.Init();
+
+                var done = (DateTime.UtcNow - now);
+                Logger.Info("Kernel.Init completed in {0}{1} minutes and {2} seconds.", done.Hours > 0 ? done.Hours + " Hours " : "", done.Minutes, done.Seconds);
+
+                await OnKernelLoaded();
+            }
+            catch (Exception ex)
+            {
+                Logger.ErrorException("Error launching application", ex);
+
+                MessageBox.Show("There was an error launching Media Browser: " + ex.Message);
+
+                // Shutdown the app with an error code
+                Shutdown(1);
+            }
+        }
+
+        /// <summary>
+        /// Called when [kernel loaded].
+        /// </summary>
+        /// <returns>Task.</returns>
+        protected Task OnKernelLoaded()
+        {
+            return Task.Run(() =>
+            {
+                Kernel.ConfigurationUpdated += Kernel_ConfigurationUpdated;
+
+                ConfigureClickOnceStartup();
+            });
+        }
+
+        /// <summary>
+        /// Handles the ConfigurationUpdated event of the Kernel control.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
+        void Kernel_ConfigurationUpdated(object sender, EventArgs e)
+        {
+            if (!LastRunAtStartupValue.HasValue || LastRunAtStartupValue.Value != Kernel.Configuration.RunAtStartup)
+            {
+                ConfigureClickOnceStartup();
+            }
+        }
+
+        /// <summary>
+        /// Configures the click once startup.
+        /// </summary>
+        private void ConfigureClickOnceStartup()
+        {
+            if (!ApplicationDeployment.IsNetworkDeployed)
+            {
+                return;
+            }
+
+            try
+            {
+                var clickOnceHelper = new ClickOnceHelper(PublisherName, ProductName, SuiteName);
+
+                if (Kernel.Configuration.RunAtStartup)
+                {
+                    clickOnceHelper.UpdateUninstallParameters(UninstallerFileName);
+                    clickOnceHelper.AddShortcutToStartup();
+                }
+                else
+                {
+                    clickOnceHelper.RemoveShortcutFromStartup();
+                }
+
+                LastRunAtStartupValue = Kernel.Configuration.RunAtStartup;
+            }
+            catch (Exception ex)
+            {
+                Logger.ErrorException("Error configuring ClickOnce", ex);
+            }
+        }
+
+        /// <summary>
+        /// Raises the <see cref="E:System.Windows.Application.Exit" /> event.
+        /// </summary>
+        /// <param name="e">An <see cref="T:System.Windows.ExitEventArgs" /> that contains the event data.</param>
+        protected override void OnExit(ExitEventArgs e)
+        {
+            ReleaseMutex();
+
+            base.OnExit(e);
+
+            Kernel.Dispose();
+        }
+
+        /// <summary>
+        /// Releases the mutex.
+        /// </summary>
+        private void ReleaseMutex()
+        {
+            if (SingleInstanceMutex == null)
+            {
+                return;
+            }
+
+            SingleInstanceMutex.ReleaseMutex();
+            SingleInstanceMutex.Close();
+            SingleInstanceMutex.Dispose();
+            SingleInstanceMutex = null;
         }
 
         /// <summary>
@@ -179,21 +369,105 @@ namespace MediaBrowser.ServerApplication
         }
 
         /// <summary>
-        /// Instantiates the kernel.
+        /// Restarts this instance.
+        /// </summary>
+        /// <exception cref="System.NotImplementedException"></exception>
+        public void Restart()
+        {
+            Dispatcher.Invoke(ReleaseMutex);
+
+            Kernel.Dispose();
+
+            System.Windows.Forms.Application.Restart();
+
+            Dispatcher.Invoke(Shutdown);
+        }
+
+        /// <summary>
+        /// Reloads the logger.
+        /// </summary>
+        /// <exception cref="System.NotImplementedException"></exception>
+        public void ReloadLogger()
+        {
+            LogFilePath = Path.Combine(Kernel.ApplicationPaths.LogDirectoryPath, "Server-" + DateTime.Now.Ticks + ".log");
+
+            NlogManager.AddFileTarget(LogFilePath, Kernel.Configuration.EnableDebugLevelLogging);
+        }
+        
+        /// <summary>
+        /// Gets the image.
+        /// </summary>
+        /// <param name="uri">The URI.</param>
+        /// <returns>Image.</returns>
+        /// <exception cref="System.ArgumentNullException">uri</exception>
+        public Image GetImage(string uri)
+        {
+            if (string.IsNullOrEmpty(uri))
+            {
+                throw new ArgumentNullException("uri");
+            }
+
+            return GetImage(new Uri(uri));
+        }
+
+        /// <summary>
+        /// Gets the image.
+        /// </summary>
+        /// <param name="uri">The URI.</param>
+        /// <returns>Image.</returns>
+        /// <exception cref="System.ArgumentNullException">uri</exception>
+        public Image GetImage(Uri uri)
+        {
+            if (uri == null)
+            {
+                throw new ArgumentNullException("uri");
+            }
+
+            return new Image { Source = GetBitmapImage(uri) };
+        }
+
+        /// <summary>
+        /// Gets the bitmap image.
         /// </summary>
-        /// <returns>IKernel.</returns>
-        protected override IKernel InstantiateKernel()
+        /// <param name="uri">The URI.</param>
+        /// <returns>BitmapImage.</returns>
+        /// <exception cref="System.ArgumentNullException">uri</exception>
+        public BitmapImage GetBitmapImage(string uri)
         {
-            return new Kernel(new PismoIsoManager(Logger), new DotNetZipClient(), new BdInfoExaminer(), Logger);
+            if (string.IsNullOrEmpty(uri))
+            {
+                throw new ArgumentNullException("uri");
+            }
+
+            return GetBitmapImage(new Uri(uri));
         }
 
         /// <summary>
-        /// Instantiates the main window.
+        /// Gets the bitmap image.
         /// </summary>
-        /// <returns>Window.</returns>
-        protected override Window InstantiateMainWindow()
+        /// <param name="uri">The URI.</param>
+        /// <returns>BitmapImage.</returns>
+        /// <exception cref="System.ArgumentNullException">uri</exception>
+        public BitmapImage GetBitmapImage(Uri uri)
         {
-            return new MainWindow(Logger);
+            if (uri == null)
+            {
+                throw new ArgumentNullException("uri");
+            }
+
+            var bitmap = new BitmapImage
+            {
+                CreateOptions = BitmapCreateOptions.DelayCreation,
+                CacheOption = BitmapCacheOption.OnDemand,
+                UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.CacheIfAvailable)
+            };
+
+            bitmap.BeginInit();
+            bitmap.UriSource = uri;
+            bitmap.EndInit();
+
+            RenderOptions.SetBitmapScalingMode(bitmap, BitmapScalingMode.Fant);
+            return bitmap;
         }
     }
 }

+ 1 - 2
MediaBrowser.ServerApplication/Controls/ItemUpdateNotification.xaml.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;

+ 1 - 2
MediaBrowser.ServerApplication/Controls/MultiItemUpdateNotification.xaml.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
 using System;

+ 1 - 1
MediaBrowser.Common/Logging/LogWindow.xaml → MediaBrowser.ServerApplication/Logging/LogWindow.xaml

@@ -1,4 +1,4 @@
-<Window x:Class="MediaBrowser.Common.Logging.LogWindow"
+<Window x:Class="MediaBrowser.ServerApplication.Logging.LogWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Title="Media Browser Log" Height="300" Width="968">

+ 1 - 1
MediaBrowser.Common/Logging/LogWindow.xaml.cs → MediaBrowser.ServerApplication/Logging/LogWindow.xaml.cs

@@ -7,7 +7,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Windows;
 
-namespace MediaBrowser.Common.Logging
+namespace MediaBrowser.ServerApplication.Logging
 {
     /// <summary>
     /// Interaction logic for LogWindow.xaml

+ 1 - 1
MediaBrowser.Common/Logging/WindowTraceListener.cs → MediaBrowser.ServerApplication/Logging/WindowTraceListener.cs

@@ -1,6 +1,6 @@
 using System.Diagnostics;
 
-namespace MediaBrowser.Common.Logging
+namespace MediaBrowser.ServerApplication.Logging
 {
     /// <summary>
     /// Class WindowTraceListener

+ 2 - 2
MediaBrowser.ServerApplication/MainWindow.xaml.cs

@@ -1,9 +1,9 @@
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Controller;
+using MediaBrowser.Controller;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.ServerApplication.Controls;
+using MediaBrowser.ServerApplication.Logging;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;

+ 18 - 0
MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj

@@ -120,6 +120,10 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath>
     </Reference>
+    <Reference Include="NLog, Version=2.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\NLog.2.0.0.2000\lib\net40\NLog.dll</HintPath>
+    </Reference>
     <Reference Include="Platinum.Managed, Version=1.0.4794.22684, Culture=neutral, processorArchitecture=x86">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\ThirdParty\UPnP\Libs\Platinum.Managed.dll</HintPath>
@@ -134,9 +138,11 @@
     <Reference Include="System.Data.SQLite.Linq">
       <HintPath>..\packages\System.Data.SQLite.1.0.84.0\lib\net45\System.Data.SQLite.Linq.dll</HintPath>
     </Reference>
+    <Reference Include="System.Deployment" />
     <Reference Include="System.Drawing" />
     <Reference Include="System.Runtime.Remoting" />
     <Reference Include="System.Web.Extensions" />
+    <Reference Include="System.Windows.Forms" />
     <Reference Include="System.Xml" />
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Core" />
@@ -166,6 +172,10 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="Logging\LogWindow.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
     <Page Include="MainWindow.xaml">
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
@@ -185,6 +195,10 @@
     <Compile Include="LibraryExplorer.xaml.cs">
       <DependentUpon>LibraryExplorer.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Logging\LogWindow.xaml.cs">
+      <DependentUpon>LogWindow.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Logging\WindowTraceListener.cs" />
     <Compile Include="MainWindow.xaml.cs">
       <DependentUpon>MainWindow.xaml</DependentUpon>
       <SubType>Code</SubType>
@@ -238,6 +252,10 @@
       <Project>{5356ae30-6a6e-4a64-81e3-f76c50595e64}</Project>
       <Name>MediaBrowser.IsoMounter</Name>
     </ProjectReference>
+    <ProjectReference Include="..\MediaBrowser.Logging.NLog\MediaBrowser.Logging.NLog.csproj">
+      <Project>{67310740-0ec4-4dc2-9921-33df38b20167}</Project>
+      <Name>MediaBrowser.Logging.NLog</Name>
+    </ProjectReference>
     <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
       <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
       <Name>MediaBrowser.Model</Name>

BIN
MediaBrowser.ServerApplication/MediaBrowser.ServerApplication_TemporaryKey.pfx


+ 1 - 0
MediaBrowser.ServerApplication/packages.config

@@ -2,5 +2,6 @@
 <packages>
   <package id="DotNetZip" version="1.9.1.8" targetFramework="net45" />
   <package id="Hardcodet.Wpf.TaskbarNotification" version="1.0.4.0" targetFramework="net45" />
+  <package id="NLog" version="2.0.0.2000" targetFramework="net45" />
   <package id="System.Data.SQLite" version="1.0.84.0" targetFramework="net45" />
 </packages>

+ 6 - 3
MediaBrowser.UI.Uninstall/MediaBrowser.UI.Uninstall.csproj

@@ -44,9 +44,6 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="..\MediaBrowser.Common\Updates\ClickOnceHelper.cs">
-      <Link>ClickOnceHelper.cs</Link>
-    </Compile>
     <Compile Include="Globals.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
@@ -54,6 +51,12 @@
   <ItemGroup>
     <None Include="App.config" />
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
+      <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
+      <Name>MediaBrowser.Common</Name>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

+ 12 - 0
MediaBrowser.UI.sln

@@ -21,6 +21,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.IsoMounter", "
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.UI.Controls", "MediaBrowser.UI.Controls\MediaBrowser.UI.Controls.csproj", "{1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Logging.NLog", "MediaBrowser.Logging.NLog\MediaBrowser.Logging.NLog.csproj", "{67310740-0EC4-4DC2-9921-33DF38B20167}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -143,6 +145,16 @@ Global
 		{1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
 		{1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}.Release|Mixed Platforms.Build.0 = Release|Any CPU
 		{1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}.Release|x86.ActiveCfg = Release|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Release|Any CPU.Build.0 = Release|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 3 - 4
MediaBrowser.UI/App.xaml

@@ -1,7 +1,6 @@
-<z:BaseApplication x:Class="MediaBrowser.UI.App"
+<Application x:Class="MediaBrowser.UI.App"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-             xmlns:z="clr-namespace:MediaBrowser.Common.UI;assembly=MediaBrowser.Common">
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
     <Application.Resources>
         <ResourceDictionary>
             <ResourceDictionary.MergedDictionaries>
@@ -13,4 +12,4 @@
             </ResourceDictionary.MergedDictionaries>
         </ResourceDictionary>
     </Application.Resources>
-</z:BaseApplication>
+</Application>

+ 250 - 17
MediaBrowser.UI/App.xaml.cs

@@ -1,10 +1,13 @@
-using MediaBrowser.ApiInteraction;
+using System.Deployment.Application;
+using System.Net.Cache;
+using System.Windows.Media;
+using MediaBrowser.ApiInteraction;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Common.UI;
+using MediaBrowser.Common.Updates;
 using MediaBrowser.IsoMounter;
+using MediaBrowser.Logging.Nlog;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Logging;
@@ -24,14 +27,21 @@ using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Media.Imaging;
+using Microsoft.Win32;
 
 namespace MediaBrowser.UI
 {
     /// <summary>
     /// Interaction logic for App.xaml
     /// </summary>
-    public partial class App : BaseApplication, IApplication
+    public partial class App : Application, IApplicationHost
     {
+        /// <summary>
+        /// Gets or sets a value indicating whether [last run at startup value].
+        /// </summary>
+        /// <value><c>null</c> if [last run at startup value] contains no value, <c>true</c> if [last run at startup value]; otherwise, <c>false</c>.</value>
+        private bool? LastRunAtStartupValue { get; set; }
+        
         /// <summary>
         /// Gets or sets the clock timer.
         /// </summary>
@@ -43,11 +53,39 @@ namespace MediaBrowser.UI
         /// <value>The server configuration timer.</value>
         private Timer ServerConfigurationTimer { get; set; }
 
+        /// <summary>
+        /// The single instance mutex
+        /// </summary>
+        private Mutex SingleInstanceMutex;
+
+        /// <summary>
+        /// Gets or sets the kernel.
+        /// </summary>
+        /// <value>The kernel.</value>
+        protected IKernel Kernel { get; set; }
+
+        /// <summary>
+        /// Gets or sets the logger.
+        /// </summary>
+        /// <value>The logger.</value>
+        protected ILogger Logger { get; set; }
+
+        /// <summary>
+        /// Gets or sets the log file path.
+        /// </summary>
+        /// <value>The log file path.</value>
+        private string LogFilePath { get; set; }
+
+        /// <summary>
+        /// Occurs when [property changed].
+        /// </summary>
+        public event PropertyChangedEventHandler PropertyChanged;
+
         /// <summary>
         /// Gets the name of the product.
         /// </summary>
         /// <value>The name of the product.</value>
-        protected override string ProductName
+        protected string ProductName
         {
             get { return Globals.ProductName; }
         }
@@ -56,7 +94,7 @@ namespace MediaBrowser.UI
         /// Gets the name of the publisher.
         /// </summary>
         /// <value>The name of the publisher.</value>
-        protected override string PublisherName
+        protected string PublisherName
         {
             get { return Globals.PublisherName; }
         }
@@ -65,7 +103,7 @@ namespace MediaBrowser.UI
         /// Gets the name of the suite.
         /// </summary>
         /// <value>The name of the suite.</value>
-        protected override string SuiteName
+        protected string SuiteName
         {
             get { return Globals.SuiteName; }
         }
@@ -74,7 +112,7 @@ namespace MediaBrowser.UI
         /// Gets the name of the uninstaller file.
         /// </summary>
         /// <value>The name of the uninstaller file.</value>
-        protected override string UninstallerFileName
+        protected string UninstallerFileName
         {
             get { return "MediaBrowser.UI.Uninstall.exe"; }
         }
@@ -236,7 +274,7 @@ namespace MediaBrowser.UI
         [STAThread]
         public static void Main()
         {
-            var application = new App(LogManager.GetLogger("App"));
+            var application = new App(new NLogger("App"));
             application.InitializeComponent();
 
             application.Run();
@@ -247,25 +285,26 @@ namespace MediaBrowser.UI
         /// </summary>
         /// <param name="logger">The logger.</param>
         public App(ILogger logger)
-            : base(logger)
         {
+            Logger = logger;
 
+            InitializeComponent();
         }
         
         /// <summary>
         /// Instantiates the kernel.
         /// </summary>
         /// <returns>IKernel.</returns>
-        protected override IKernel InstantiateKernel()
+        protected IKernel InstantiateKernel()
         {
-            return new UIKernel(new PismoIsoManager(Logger), Logger);
+            return new UIKernel(this, new PismoIsoManager(Logger), Logger);
         }
 
         /// <summary>
         /// Instantiates the main window.
         /// </summary>
         /// <returns>Window.</returns>
-        protected override Window InstantiateMainWindow()
+        protected Window InstantiateMainWindow()
         {
             HiddenWindow = new HiddenWindow { };
 
@@ -361,7 +400,7 @@ namespace MediaBrowser.UI
         /// <summary>
         /// Loads the kernel.
         /// </summary>
-        protected override async void LoadKernel()
+        protected async void LoadKernel()
         {
             // Without this the app will shutdown after the splash screen closes
             ShutdownMode = ShutdownMode.OnExplicitShutdown;
@@ -378,7 +417,7 @@ namespace MediaBrowser.UI
 
                 ShutdownMode = System.Windows.ShutdownMode.OnLastWindowClose;
 
-                await OnKernelLoaded();
+                OnKernelLoaded();
 
                 InstantiateMainWindow().Show();
 
@@ -401,9 +440,11 @@ namespace MediaBrowser.UI
         /// Called when [kernel loaded].
         /// </summary>
         /// <returns>Task.</returns>
-        protected override async Task OnKernelLoaded()
+        protected void OnKernelLoaded()
         {
-            await base.OnKernelLoaded().ConfigureAwait(false);
+            Kernel.ConfigurationUpdated += Kernel_ConfigurationUpdated;
+
+            ConfigureClickOnceStartup();
 
             PropertyChanged += AppPropertyChanged;
 
@@ -421,6 +462,71 @@ namespace MediaBrowser.UI
             }
         }
 
+        /// <summary>
+        /// Raises the <see cref="E:System.Windows.Application.Startup" /> event.
+        /// </summary>
+        /// <param name="e">A <see cref="T:System.Windows.StartupEventArgs" /> that contains the event data.</param>
+        protected override void OnStartup(StartupEventArgs e)
+        {
+            bool createdNew;
+            SingleInstanceMutex = new Mutex(true, @"Local\" + GetType().Assembly.GetName().Name, out createdNew);
+            if (!createdNew)
+            {
+                SingleInstanceMutex = null;
+                Shutdown();
+                return;
+            }
+
+            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
+            LoadKernel();
+
+            SystemEvents.SessionEnding += SystemEvents_SessionEnding;
+        }
+
+        /// <summary>
+        /// Handles the UnhandledException event of the CurrentDomain control.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="UnhandledExceptionEventArgs" /> instance containing the event data.</param>
+        void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
+        {
+            var exception = (Exception)e.ExceptionObject;
+
+            Logger.ErrorException("UnhandledException", exception);
+
+            MessageBox.Show("Unhandled exception: " + exception.Message);
+        }
+
+        /// <summary>
+        /// Called when [property changed].
+        /// </summary>
+        /// <param name="info">The info.</param>
+        public void OnPropertyChanged(String info)
+        {
+            if (PropertyChanged != null)
+            {
+                try
+                {
+                    PropertyChanged(this, new PropertyChangedEventArgs(info));
+                }
+                catch (Exception ex)
+                {
+                    Logger.ErrorException("Error in event handler", ex);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Handles the SessionEnding event of the SystemEvents control.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="SessionEndingEventArgs" /> instance containing the event data.</param>
+        void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
+        {
+            // Try to shut down gracefully
+            Shutdown();
+        }
+        
         /// <summary>
         /// Raises the <see cref="E:System.Windows.Application.Exit" /> event.
         /// </summary>
@@ -441,9 +547,29 @@ namespace MediaBrowser.UI
                 UIKernel.Instance.SaveConfiguration();
             }
 
+            ReleaseMutex();
+
             base.OnExit(e);
+
+            Kernel.Dispose();
         }
 
+        /// <summary>
+        /// Releases the mutex.
+        /// </summary>
+        private void ReleaseMutex()
+        {
+            if (SingleInstanceMutex == null)
+            {
+                return;
+            }
+
+            SingleInstanceMutex.ReleaseMutex();
+            SingleInstanceMutex.Close();
+            SingleInstanceMutex.Dispose();
+            SingleInstanceMutex = null;
+        }
+        
         /// <summary>
         /// Apps the property changed.
         /// </summary>
@@ -771,5 +897,112 @@ namespace MediaBrowser.UI
                 return bitmapImage;
             }
         }
+        
+        /// <summary>
+        /// Handles the ConfigurationUpdated event of the Kernel control.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
+        void Kernel_ConfigurationUpdated(object sender, EventArgs e)
+        {
+            if (!LastRunAtStartupValue.HasValue || LastRunAtStartupValue.Value != Kernel.Configuration.RunAtStartup)
+            {
+                ConfigureClickOnceStartup();
+            }
+        }
+
+        /// <summary>
+        /// Configures the click once startup.
+        /// </summary>
+        private void ConfigureClickOnceStartup()
+        {
+            if (!ApplicationDeployment.IsNetworkDeployed)
+            {
+                return;
+            }
+
+            try
+            {
+                var clickOnceHelper = new ClickOnceHelper(PublisherName, ProductName, SuiteName);
+
+                if (Kernel.Configuration.RunAtStartup)
+                {
+                    clickOnceHelper.UpdateUninstallParameters(UninstallerFileName);
+                    clickOnceHelper.AddShortcutToStartup();
+                }
+                else
+                {
+                    clickOnceHelper.RemoveShortcutFromStartup();
+                }
+
+                LastRunAtStartupValue = Kernel.Configuration.RunAtStartup;
+            }
+            catch (Exception ex)
+            {
+                Logger.ErrorException("Error configuring ClickOnce", ex);
+            }
+        }
+
+        public void Restart()
+        {
+            Dispatcher.Invoke(ReleaseMutex);
+
+            Kernel.Dispose();
+
+            System.Windows.Forms.Application.Restart();
+
+            Dispatcher.Invoke(Shutdown);
+        }
+
+        public void ReloadLogger()
+        {
+            LogFilePath = Path.Combine(Kernel.ApplicationPaths.LogDirectoryPath, "Server-" + DateTime.Now.Ticks + ".log");
+
+            NlogManager.AddFileTarget(LogFilePath, Kernel.Configuration.EnableDebugLevelLogging);
+        }        
+        
+        /// <summary>
+        /// Gets the bitmap image.
+        /// </summary>
+        /// <param name="uri">The URI.</param>
+        /// <returns>BitmapImage.</returns>
+        /// <exception cref="System.ArgumentNullException">uri</exception>
+        public BitmapImage GetBitmapImage(string uri)
+        {
+            if (string.IsNullOrEmpty(uri))
+            {
+                throw new ArgumentNullException("uri");
+            }
+
+            return GetBitmapImage(new Uri(uri));
+        }
+
+        /// <summary>
+        /// Gets the bitmap image.
+        /// </summary>
+        /// <param name="uri">The URI.</param>
+        /// <returns>BitmapImage.</returns>
+        /// <exception cref="System.ArgumentNullException">uri</exception>
+        public BitmapImage GetBitmapImage(Uri uri)
+        {
+            if (uri == null)
+            {
+                throw new ArgumentNullException("uri");
+            }
+
+            var bitmap = new BitmapImage
+            {
+                CreateOptions = BitmapCreateOptions.DelayCreation,
+                CacheOption = BitmapCacheOption.OnDemand,
+                UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.CacheIfAvailable)
+            };
+
+            bitmap.BeginInit();
+            bitmap.UriSource = uri;
+            bitmap.EndInit();
+
+            RenderOptions.SetBitmapScalingMode(bitmap, BitmapScalingMode.Fant);
+            return bitmap;
+        }
     }
 }

+ 3 - 10
MediaBrowser.UI/Controller/UIKernel.cs

@@ -1,7 +1,6 @@
 using MediaBrowser.ApiInteraction;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Model.Connectivity;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Net;
@@ -10,13 +9,9 @@ using MediaBrowser.UI.Playback;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel.Composition;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
 using System.Net;
 using System.Net.Cache;
 using System.Net.Http;
-using System.Reflection;
 using System.Threading.Tasks;
 
 namespace MediaBrowser.UI.Controller
@@ -47,8 +42,8 @@ namespace MediaBrowser.UI.Controller
         /// <summary>
         /// Initializes a new instance of the <see cref="UIKernel" /> class.
         /// </summary>
-        public UIKernel(IIsoManager isoManager, ILogger logger)
-            : base(isoManager, logger)
+        public UIKernel(IApplicationHost appHost, IIsoManager isoManager, ILogger logger)
+            : base(appHost, isoManager, logger)
         {
             Instance = this;
         }
@@ -122,9 +117,7 @@ namespace MediaBrowser.UI.Controller
         {
             DisposeApiClient();
 
-            var logger = LogManager.GetLogger("ApiClient");
-
-            ApiClient = new ApiClient(logger, new AsyncHttpClient(new WebRequestHandler
+            ApiClient = new ApiClient(Logger, new AsyncHttpClient(new WebRequestHandler
             {
                 AutomaticDecompression = DecompressionMethods.Deflate,
                 CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate)

+ 1 - 1
MediaBrowser.UI/ImageViewerWindow.xaml.cs

@@ -35,7 +35,7 @@ namespace MediaBrowser.UI
         {
             base.OnLoaded();
 
-            Image.Source = App.Instance.GetBitmapImage(Images.First().Item1);
+            //Image.Source = App.Instance.GetBitmapImage(Images.First().Item1);
         }
     }
 }

+ 0 - 2
MediaBrowser.UI/MainWindow.xaml.cs

@@ -1,12 +1,10 @@
 using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Net;
 using MediaBrowser.UI.Controller;
 using MediaBrowser.UI.Controls;
 using System;
-using System.ComponentModel;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;

+ 5 - 0
MediaBrowser.UI/MediaBrowser.UI.csproj

@@ -116,6 +116,7 @@
     <Reference Include="System" />
     <Reference Include="System.ComponentModel.Composition" />
     <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
     <Reference Include="System.Drawing" />
     <Reference Include="System.Net" />
     <Reference Include="System.Net.Http" />
@@ -307,6 +308,10 @@
       <Project>{5356ae30-6a6e-4a64-81e3-f76c50595e64}</Project>
       <Name>MediaBrowser.IsoMounter</Name>
     </ProjectReference>
+    <ProjectReference Include="..\MediaBrowser.Logging.NLog\MediaBrowser.Logging.NLog.csproj">
+      <Project>{67310740-0ec4-4dc2-9921-33df38b20167}</Project>
+      <Name>MediaBrowser.Logging.NLog</Name>
+    </ProjectReference>
     <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
       <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
       <Name>MediaBrowser.Model</Name>

BIN
MediaBrowser.UI/MediaBrowser.UI_TemporaryKey.pfx


+ 2 - 3
MediaBrowser.UI/Playback/BaseMediaPlayer.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Common.Events;
-using MediaBrowser.Common.Logging;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Net;
@@ -212,9 +211,9 @@ namespace MediaBrowser.UI.Playback
         /// <summary>
         /// Initializes a new instance of the <see cref="BaseMediaPlayer" /> class.
         /// </summary>
-        protected BaseMediaPlayer()
+        protected BaseMediaPlayer(ILogger logger)
         {
-            Logger = LogManager.GetLogger(GetType().Name);
+            Logger = logger;
         }
 
         /// <summary>

+ 6 - 2
MediaBrowser.UI/Playback/ExternalPlayer/BaseExternalPlayer.cs

@@ -1,5 +1,5 @@
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Logging;
 using MediaBrowser.UI.Configuration;
 using MediaBrowser.UI.UserInput;
 using System;
@@ -16,6 +16,10 @@ namespace MediaBrowser.UI.Playback.ExternalPlayer
     /// </summary>
     public abstract class BaseExternalPlayer : BaseMediaPlayer
     {
+        protected BaseExternalPlayer(ILogger logger) : base(logger)
+        {
+        }
+
         /// <summary>
         /// Gets a value indicating whether this instance can mute.
         /// </summary>

+ 7 - 0
MediaBrowser.UI/Playback/ExternalPlayer/GenericExternalPlayer.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Model.Dto;
 using System.ComponentModel.Composition;
+using MediaBrowser.Model.Logging;
 
 namespace MediaBrowser.UI.Playback.ExternalPlayer
 {
@@ -9,6 +10,12 @@ namespace MediaBrowser.UI.Playback.ExternalPlayer
     [Export(typeof(BaseMediaPlayer))]
     public class GenericExternalPlayer : BaseExternalPlayer
     {
+        [ImportingConstructor]
+        public GenericExternalPlayer([Import("logger")] ILogger logger)
+            : base(logger)
+        {
+        }
+
         /// <summary>
         /// Gets the name.
         /// </summary>

+ 5 - 0
MediaBrowser.UI/Playback/InternalPlayer/BaseInternalMediaPlayer.cs

@@ -1,4 +1,5 @@
 using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Logging;
 using MediaBrowser.UI.Configuration;
 using System.Collections.Generic;
 using System.Windows;
@@ -10,6 +11,10 @@ namespace MediaBrowser.UI.Playback.InternalPlayer
     /// </summary>
     public abstract class BaseInternalMediaPlayer : BaseMediaPlayer
     {
+        protected BaseInternalMediaPlayer(ILogger logger) : base(logger)
+        {
+        }
+
         /// <summary>
         /// Ensures the media player created.
         /// </summary>

+ 9 - 3
MediaBrowser.UI/Playback/NVlc/InternalMediaPlayerNVlc.cs

@@ -1,20 +1,20 @@
-using System.IO;
-using Declarations.Events;
+using Declarations.Events;
 using Declarations.Media;
 using Declarations.Players;
 using Implementation;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
 using MediaBrowser.UI.Configuration;
 using MediaBrowser.UI.Playback.InternalPlayer;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel.Composition;
 using System.Drawing;
+using System.IO;
 using System.Linq;
 using System.Threading.Tasks;
 using System.Windows.Forms;
-using MediaState = Declarations.MediaState;
 
 namespace MediaBrowser.UI.Playback.NVlc
 {
@@ -24,6 +24,12 @@ namespace MediaBrowser.UI.Playback.NVlc
     [Export(typeof(BaseMediaPlayer))]
     public class InternalMediaPlayerNVlc : BaseInternalMediaPlayer
     {
+        [ImportingConstructor]
+        public InternalMediaPlayerNVlc([Import("logger")] ILogger logger)
+            : base(logger)
+        {
+        }
+
         /// <summary>
         /// Gets or sets the media player factory.
         /// </summary>

+ 1 - 2
MediaBrowser.UI/ViewModels/DtoBaseItemViewModel.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.UI.Pages;
 using System;

+ 1 - 1
MediaBrowser.WebDashboard/Api/DashboardInfoWebSocketListener.cs

@@ -39,7 +39,7 @@ namespace MediaBrowser.WebDashboard.Api
         /// <returns>Task{IEnumerable{TaskInfo}}.</returns>
         protected override Task<DashboardInfo> GetDataToSend(object state)
         {
-            return Task.FromResult(DashboardService.GetDashboardInfo((Kernel)Kernel));
+            return Task.FromResult(DashboardService.GetDashboardInfo((Kernel)Kernel, Logger));
         }
     }
 }

+ 7 - 3
MediaBrowser.WebDashboard/Api/DashboardService.cs

@@ -5,6 +5,7 @@ using MediaBrowser.Common.ScheduledTasks.Tasks;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Plugins;
+using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Tasks;
 using ServiceStack.ServiceHost;
 using ServiceStack.WebHost.Endpoints;
@@ -97,18 +98,21 @@ namespace MediaBrowser.WebDashboard.Api
         {
             var kernel = (Kernel)Kernel;
 
-            return GetDashboardInfo(kernel);
+            return GetDashboardInfo(kernel, Logger);
         }
 
         /// <summary>
         /// Gets the dashboard info.
         /// </summary>
         /// <param name="kernel">The kernel.</param>
+        /// <param name="logger">The logger.</param>
         /// <returns>DashboardInfo.</returns>
-        public static DashboardInfo GetDashboardInfo(Kernel kernel)
+        public static DashboardInfo GetDashboardInfo(Kernel kernel, ILogger logger)
         {
             var connections = kernel.UserManager.ActiveConnections.ToArray();
 
+            var dtoBuilder = new DtoBuilder(logger);
+
             return new DashboardInfo
             {
                 SystemInfo = kernel.GetSystemInfo(),
@@ -121,7 +125,7 @@ namespace MediaBrowser.WebDashboard.Api
 
                 ActiveConnections = connections,
 
-                Users = kernel.Users.Where(u => connections.Any(c => c.UserId == u.Id)).Select(DtoBuilder.GetDtoUser).ToArray()
+                Users = kernel.Users.Where(u => connections.Any(c => c.UserId == u.Id)).Select(dtoBuilder.GetDtoUser).ToArray()
             };
         }
 

+ 16 - 0
MediaBrowser.sln

@@ -49,6 +49,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Sqlite"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.WorldWeatherOnline", "MediaBrowser.Server.WorldWeatherOnline\MediaBrowser.Server.WorldWeatherOnline.csproj", "{973CA45C-8362-490B-8327-C68098FD4891}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Logging.NLog", "MediaBrowser.Logging.NLog\MediaBrowser.Logging.NLog.csproj", "{67310740-0EC4-4DC2-9921-33DF38B20167}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -319,6 +321,20 @@ Global
 		{973CA45C-8362-490B-8327-C68098FD4891}.Release|Win32.ActiveCfg = Release|Any CPU
 		{973CA45C-8362-490B-8327-C68098FD4891}.Release|x64.ActiveCfg = Release|Any CPU
 		{973CA45C-8362-490B-8327-C68098FD4891}.Release|x86.ActiveCfg = Release|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Release|Any CPU.Build.0 = Release|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Release|Win32.ActiveCfg = Release|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Release|x64.ActiveCfg = Release|Any CPU
+		{67310740-0EC4-4DC2-9921-33DF38B20167}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE