update restart function

This commit is contained in:
Luke Pulverenti 2017-09-09 14:51:24 -04:00
parent 9a5a6f569d
commit 4ceb9eb6c5
7 changed files with 172 additions and 190 deletions

View file

@ -1,5 +1,4 @@
using Emby.Common.Implementations; using Emby.Common.Implementations.Serialization;
using Emby.Common.Implementations.Serialization;
using Emby.Dlna; using Emby.Dlna;
using Emby.Dlna.ConnectionManager; using Emby.Dlna.ConnectionManager;
using Emby.Dlna.ContentDirectory; using Emby.Dlna.ContentDirectory;
@ -8,12 +7,16 @@ using Emby.Dlna.MediaReceiverRegistrar;
using Emby.Dlna.Ssdp; using Emby.Dlna.Ssdp;
using Emby.Drawing; using Emby.Drawing;
using Emby.Photos; using Emby.Photos;
using Emby.Server.Core.Cryptography;
using Emby.Server.Implementations.Activity; using Emby.Server.Implementations.Activity;
using Emby.Server.Implementations.Archiving;
using Emby.Server.Implementations.Channels; using Emby.Server.Implementations.Channels;
using Emby.Server.Implementations.Collections; using Emby.Server.Implementations.Collections;
using Emby.Server.Implementations.Configuration; using Emby.Server.Implementations.Configuration;
using Emby.Server.Implementations.Cryptography;
using Emby.Server.Implementations.Data; using Emby.Server.Implementations.Data;
using Emby.Server.Implementations.Devices; using Emby.Server.Implementations.Devices;
using Emby.Server.Implementations.Diagnostics;
using Emby.Server.Implementations.Dto; using Emby.Server.Implementations.Dto;
using Emby.Server.Implementations.FFMpeg; using Emby.Server.Implementations.FFMpeg;
using Emby.Server.Implementations.HttpServer; using Emby.Server.Implementations.HttpServer;
@ -23,14 +26,20 @@ using Emby.Server.Implementations.Library;
using Emby.Server.Implementations.LiveTv; using Emby.Server.Implementations.LiveTv;
using Emby.Server.Implementations.Localization; using Emby.Server.Implementations.Localization;
using Emby.Server.Implementations.MediaEncoder; using Emby.Server.Implementations.MediaEncoder;
using Emby.Server.Implementations.Migrations; using Emby.Server.Implementations.Net;
using Emby.Server.Implementations.Notifications; using Emby.Server.Implementations.Notifications;
using Emby.Server.Implementations.Playlists; using Emby.Server.Implementations.Playlists;
using Emby.Server.Implementations.Reflection;
using Emby.Server.Implementations.ScheduledTasks;
using Emby.Server.Implementations.Security; using Emby.Server.Implementations.Security;
using Emby.Server.Implementations.Serialization;
using Emby.Server.Implementations.Session; using Emby.Server.Implementations.Session;
using Emby.Server.Implementations.Social; using Emby.Server.Implementations.Social;
using Emby.Server.Implementations.Threading;
using Emby.Server.Implementations.TV; using Emby.Server.Implementations.TV;
using Emby.Server.Implementations.Updates; using Emby.Server.Implementations.Updates;
using Emby.Server.Implementations.Xml;
using Emby.Server.MediaEncoding.Subtitles;
using MediaBrowser.Api; using MediaBrowser.Api;
using MediaBrowser.Common; using MediaBrowser.Common;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Configuration;
@ -52,9 +61,6 @@ using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.MediaEncoding;
@ -72,10 +78,13 @@ using MediaBrowser.Controller.Subtitles;
using MediaBrowser.Controller.Sync; using MediaBrowser.Controller.Sync;
using MediaBrowser.Controller.TV; using MediaBrowser.Controller.TV;
using MediaBrowser.LocalMetadata.Savers; using MediaBrowser.LocalMetadata.Savers;
using MediaBrowser.MediaEncoding.BdInfo;
using MediaBrowser.Model.Activity; using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Cryptography;
using MediaBrowser.Model.Diagnostics; using MediaBrowser.Model.Diagnostics;
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
@ -87,7 +96,9 @@ using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services; using MediaBrowser.Model.Services;
using MediaBrowser.Model.Social; using MediaBrowser.Model.Social;
using MediaBrowser.Model.System; using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Text; using MediaBrowser.Model.Text;
using MediaBrowser.Model.Threading;
using MediaBrowser.Model.Updates; using MediaBrowser.Model.Updates;
using MediaBrowser.Model.Xml; using MediaBrowser.Model.Xml;
using MediaBrowser.Providers.Chapters; using MediaBrowser.Providers.Chapters;
@ -97,7 +108,6 @@ using MediaBrowser.WebDashboard.Api;
using MediaBrowser.XbmcMetadata.Providers; using MediaBrowser.XbmcMetadata.Providers;
using OpenSubtitlesHandler; using OpenSubtitlesHandler;
using ServiceStack; using ServiceStack;
using SocketHttpListener.Primitives;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
@ -111,22 +121,6 @@ using System.Security.Cryptography.X509Certificates;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Emby.Server.Core.Cryptography;
using Emby.Server.Implementations.Archiving;
using Emby.Server.Implementations.Cryptography;
using Emby.Server.Implementations.Diagnostics;
using Emby.Server.Implementations.Net;
using Emby.Server.Implementations.Reflection;
using Emby.Server.Implementations.ScheduledTasks;
using Emby.Server.Implementations.Serialization;
using Emby.Server.Implementations.Threading;
using Emby.Server.Implementations.Xml;
using Emby.Server.MediaEncoding.Subtitles;
using MediaBrowser.MediaEncoding.BdInfo;
using MediaBrowser.Model.Cryptography;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Threading;
using StringExtensions = MediaBrowser.Controller.Extensions.StringExtensions; using StringExtensions = MediaBrowser.Controller.Extensions.StringExtensions;
using X509Certificate = System.Security.Cryptography.X509Certificates.X509Certificate; using X509Certificate = System.Security.Cryptography.X509Certificates.X509Certificate;
@ -135,7 +129,7 @@ namespace Emby.Server.Implementations
/// <summary> /// <summary>
/// Class CompositionRoot /// Class CompositionRoot
/// </summary> /// </summary>
public abstract class ApplicationHost : IServerApplicationHost, IDependencyContainer public abstract class ApplicationHost : IServerApplicationHost, IDependencyContainer, IDisposable
{ {
/// <summary> /// <summary>
/// Gets a value indicating whether this instance can self restart. /// Gets a value indicating whether this instance can self restart.
@ -171,6 +165,8 @@ namespace Emby.Server.Implementations
/// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value> /// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value>
public bool HasPendingRestart { get; private set; } public bool HasPendingRestart { get; private set; }
public bool IsShuttingDown { get; private set; }
/// <summary> /// <summary>
/// Gets or sets the logger. /// Gets or sets the logger.
/// </summary> /// </summary>
@ -367,7 +363,7 @@ namespace Emby.Server.Implementations
protected IAuthService AuthService { get; private set; } protected IAuthService AuthService { get; private set; }
protected readonly StartupOptions StartupOptions; protected readonly StartupOptions StartupOptions;
private readonly string _releaseAssetFilename; protected readonly string ReleaseAssetFilename;
internal IPowerManagement PowerManagement { get; private set; } internal IPowerManagement PowerManagement { get; private set; }
internal IImageEncoder ImageEncoder { get; private set; } internal IImageEncoder ImageEncoder { get; private set; }
@ -420,7 +416,7 @@ namespace Emby.Server.Implementations
Logger = LogManager.GetLogger("App"); Logger = LogManager.GetLogger("App");
StartupOptions = options; StartupOptions = options;
_releaseAssetFilename = releaseAssetFilename; ReleaseAssetFilename = releaseAssetFilename;
PowerManagement = powerManagement; PowerManagement = powerManagement;
ImageEncoder = imageEncoder; ImageEncoder = imageEncoder;
@ -1755,25 +1751,35 @@ namespace Emby.Server.Implementations
/// <summary> /// <summary>
/// Restarts this instance. /// Restarts this instance.
/// </summary> /// </summary>
public async Task Restart() public void Restart()
{ {
if (!CanSelfRestart) if (!CanSelfRestart)
{ {
throw new PlatformNotSupportedException("The server is unable to self-restart. Please restart manually."); throw new PlatformNotSupportedException("The server is unable to self-restart. Please restart manually.");
} }
try if (IsShuttingDown)
{ {
await SessionManager.SendServerRestartNotification(CancellationToken.None).ConfigureAwait(false); return;
}
catch (Exception ex)
{
Logger.ErrorException("Error sending server restart notification", ex);
} }
Logger.Info("Calling RestartInternal"); IsShuttingDown = true;
RestartInternal(); Task.Run(async () =>
{
try
{
await SessionManager.SendServerRestartNotification(CancellationToken.None).ConfigureAwait(false);
}
catch (Exception ex)
{
Logger.ErrorException("Error sending server restart notification", ex);
}
Logger.Info("Calling RestartInternal");
RestartInternal();
});
} }
protected abstract void RestartInternal(); protected abstract void RestartInternal();
@ -1880,6 +1886,7 @@ namespace Emby.Server.Implementations
return new SystemInfo return new SystemInfo
{ {
HasPendingRestart = HasPendingRestart, HasPendingRestart = HasPendingRestart,
IsShuttingDown = IsShuttingDown,
Version = ApplicationVersion.ToString(), Version = ApplicationVersion.ToString(),
WebSocketPortNumber = HttpPort, WebSocketPortNumber = HttpPort,
FailedPluginAssemblies = FailedAssemblies.ToArray(), FailedPluginAssemblies = FailedAssemblies.ToArray(),
@ -2107,6 +2114,13 @@ namespace Emby.Server.Implementations
/// </summary> /// </summary>
public async Task Shutdown() public async Task Shutdown()
{ {
if (IsShuttingDown)
{
return;
}
IsShuttingDown = true;
try try
{ {
await SessionManager.SendServerShutdownNotification(CancellationToken.None).ConfigureAwait(false); await SessionManager.SendServerShutdownNotification(CancellationToken.None).ConfigureAwait(false);
@ -2185,22 +2199,29 @@ namespace Emby.Server.Implementations
/// <returns>Task{CheckForUpdateResult}.</returns> /// <returns>Task{CheckForUpdateResult}.</returns>
public async Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress<double> progress) public async Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress<double> progress)
{ {
var cacheLength = TimeSpan.FromHours(1); var cacheLength = TimeSpan.FromMinutes(5);
var updateLevel = SystemUpdateLevel; var updateLevel = SystemUpdateLevel;
if (updateLevel != PackageVersionClass.Release) var result = await new GithubUpdater(HttpClient, JsonSerializer).CheckForUpdateResult("MediaBrowser",
{ "Emby",
cacheLength = TimeSpan.FromMinutes(5); ApplicationVersion,
} updateLevel,
ReleaseAssetFilename,
var result = await new GithubUpdater(HttpClient, JsonSerializer).CheckForUpdateResult("MediaBrowser", "Emby", ApplicationVersion, updateLevel, _releaseAssetFilename, "MBServer",
"MBServer", "Mbserver.zip", cacheLength, cancellationToken).ConfigureAwait(false); UpdateTargetFileName,
cacheLength,
cancellationToken).ConfigureAwait(false);
HasUpdateAvailable = result.IsUpdateAvailable; HasUpdateAvailable = result.IsUpdateAvailable;
return result; return result;
} }
protected virtual string UpdateTargetFileName
{
get { return "Mbserver.zip"; }
}
/// <summary> /// <summary>
/// Updates the application. /// Updates the application.
/// </summary> /// </summary>

View file

@ -192,11 +192,7 @@ namespace MediaBrowser.Api.System
/// <param name="request">The request.</param> /// <param name="request">The request.</param>
public void Post(RestartApplication request) public void Post(RestartApplication request)
{ {
Task.Run(async () => _appHost.Restart();
{
await Task.Delay(100).ConfigureAwait(false);
await _appHost.Restart().ConfigureAwait(false);
});
} }
/// <summary> /// <summary>

View file

@ -42,6 +42,8 @@ namespace MediaBrowser.Common
/// <value><c>true</c> if this instance has pending kernel reload; otherwise, <c>false</c>.</value> /// <value><c>true</c> if this instance has pending kernel reload; otherwise, <c>false</c>.</value>
bool HasPendingRestart { get; } bool HasPendingRestart { get; }
bool IsShuttingDown { get; }
/// <summary> /// <summary>
/// Gets a value indicating whether this instance can self restart. /// Gets a value indicating whether this instance can self restart.
/// </summary> /// </summary>
@ -57,11 +59,11 @@ namespace MediaBrowser.Common
/// Notifies the pending restart. /// Notifies the pending restart.
/// </summary> /// </summary>
void NotifyPendingRestart(); void NotifyPendingRestart();
/// <summary> /// <summary>
/// Restarts this instance. /// Restarts this instance.
/// </summary> /// </summary>
Task Restart(); void Restart();
/// <summary> /// <summary>
/// Gets the application version. /// Gets the application version.

View file

@ -36,6 +36,8 @@ namespace MediaBrowser.Model.System
/// <value><c>true</c> if this instance has pending restart; otherwise, <c>false</c>.</value> /// <value><c>true</c> if this instance has pending restart; otherwise, <c>false</c>.</value>
public bool HasPendingRestart { get; set; } public bool HasPendingRestart { get; set; }
public bool IsShuttingDown { get; set; }
/// <summary> /// <summary>
/// Gets or sets a value indicating whether [supports library monitor]. /// Gets or sets a value indicating whether [supports library monitor].
/// </summary> /// </summary>

View file

@ -11,6 +11,7 @@ using System.Net.Security;
using System.Reflection; using System.Reflection;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Emby.Drawing;
using Emby.Server.Core.Cryptography; using Emby.Server.Core.Cryptography;
using Emby.Server.Core; using Emby.Server.Core;
using Emby.Server.Implementations; using Emby.Server.Implementations;
@ -18,6 +19,7 @@ using Emby.Server.Implementations.EnvironmentInfo;
using Emby.Server.Implementations.IO; using Emby.Server.Implementations.IO;
using Emby.Server.Implementations.Logging; using Emby.Server.Implementations.Logging;
using Emby.Server.Implementations.Networking; using Emby.Server.Implementations.Networking;
using MediaBrowser.Controller;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.System; using MediaBrowser.Model.System;
using Mono.Unix.Native; using Mono.Unix.Native;
@ -28,10 +30,10 @@ namespace MediaBrowser.Server.Mono
{ {
public class MainClass public class MainClass
{ {
private static ApplicationHost _appHost;
private static ILogger _logger; private static ILogger _logger;
private static IFileSystem FileSystem; private static IFileSystem FileSystem;
private static IServerApplicationPaths _appPaths;
private static ILogManager _logManager;
private static readonly TaskCompletionSource<bool> ApplicationTaskCompletionSource = new TaskCompletionSource<bool>(); private static readonly TaskCompletionSource<bool> ApplicationTaskCompletionSource = new TaskCompletionSource<bool>();
private static bool _restartOnShutdown; private static bool _restartOnShutdown;
@ -49,9 +51,12 @@ namespace MediaBrowser.Server.Mono
var customProgramDataPath = options.GetOption("-programdata"); var customProgramDataPath = options.GetOption("-programdata");
var appPaths = CreateApplicationPaths(applicationPath, customProgramDataPath); var appPaths = CreateApplicationPaths(applicationPath, customProgramDataPath);
_appPaths = appPaths;
using (var logManager = new SimpleLogManager(appPaths.LogDirectoryPath, "server")) using (var logManager = new SimpleLogManager(appPaths.LogDirectoryPath, "server"))
{ {
_logManager = logManager;
logManager.ReloadLogger(LogSeverity.Info); logManager.ReloadLogger(LogSeverity.Info);
logManager.AddConsoleOutput(); logManager.AddConsoleOutput();
@ -68,7 +73,6 @@ namespace MediaBrowser.Server.Mono
finally finally
{ {
_logger.Info("Disposing app host"); _logger.Info("Disposing app host");
_appHost.Dispose();
if (_restartOnShutdown) if (_restartOnShutdown)
{ {
@ -106,40 +110,41 @@ namespace MediaBrowser.Server.Mono
FileSystem = fileSystem; FileSystem = fileSystem;
var imageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => _appHost.HttpClient, appPaths, environmentInfo); using (var appHost = new MonoAppHost(appPaths,
_appHost = new MonoAppHost(appPaths,
logManager, logManager,
options, options,
fileSystem, fileSystem,
new PowerManagement(), new PowerManagement(),
"emby.mono.zip", "emby.mono.zip",
environmentInfo, environmentInfo,
imageEncoder, new NullImageEncoder(),
new SystemEvents(logManager.GetLogger("SystemEvents")), new SystemEvents(logManager.GetLogger("SystemEvents")),
new NetworkManager(logManager.GetLogger("NetworkManager"))); new NetworkManager(logManager.GetLogger("NetworkManager"))))
if (options.ContainsOption("-v"))
{ {
Console.WriteLine(_appHost.ApplicationVersion.ToString()); appHost.ImageProcessor.ImageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => appHost.HttpClient, appPaths, environmentInfo);
return;
if (options.ContainsOption("-v"))
{
Console.WriteLine(appHost.ApplicationVersion.ToString());
return;
}
Console.WriteLine("appHost.Init");
var initProgress = new Progress<double>();
var task = appHost.Init(initProgress);
Task.WaitAll(task);
Console.WriteLine("Running startup tasks");
task = appHost.RunStartupTasks();
Task.WaitAll(task);
task = ApplicationTaskCompletionSource.Task;
Task.WaitAll(task);
} }
Console.WriteLine("appHost.Init");
var initProgress = new Progress<double>();
var task = _appHost.Init(initProgress);
Task.WaitAll(task);
Console.WriteLine("Running startup tasks");
task = _appHost.RunStartupTasks();
Task.WaitAll(task);
task = ApplicationTaskCompletionSource.Task;
Task.WaitAll(task);
} }
private static MonoEnvironmentInfo GetEnvironmentInfo() private static MonoEnvironmentInfo GetEnvironmentInfo()
@ -231,7 +236,7 @@ namespace MediaBrowser.Server.Mono
{ {
var exception = (Exception)e.ExceptionObject; var exception = (Exception)e.ExceptionObject;
new UnhandledExceptionWriter(_appHost.ServerConfigurationManager.ApplicationPaths, _logger, _appHost.LogManager, FileSystem, new ConsoleLogger()).Log(exception); new UnhandledExceptionWriter(_appPaths, _logger, _logManager, FileSystem, new ConsoleLogger()).Log(exception);
if (!Debugger.IsAttached) if (!Debugger.IsAttached)
{ {

View file

@ -25,6 +25,7 @@ using Emby.Server.Implementations.EnvironmentInfo;
using Emby.Server.Implementations.IO; using Emby.Server.Implementations.IO;
using Emby.Server.Implementations.Logging; using Emby.Server.Implementations.Logging;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using SystemEvents = Emby.Server.Implementations.SystemEvents; using SystemEvents = Emby.Server.Implementations.SystemEvents;
@ -32,13 +33,13 @@ namespace MediaBrowser.ServerApplication
{ {
public class MainStartup public class MainStartup
{ {
private static ApplicationHost _appHost; private static IServerApplicationPaths _appPaths;
private static ILogManager _logManager;
private static ILogger _logger; private static ILogger _logger;
public static bool IsRunningAsService = false; public static bool IsRunningAsService = false;
private static bool _canRestartService = false; private static bool _canRestartService = false;
private static bool _appHostDisposed;
[DllImport("kernel32.dll", SetLastError = true)] [DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName); static extern bool SetDllDirectory(string lpPathName);
@ -46,6 +47,7 @@ namespace MediaBrowser.ServerApplication
public static string ApplicationPath; public static string ApplicationPath;
private static IFileSystem FileSystem; private static IFileSystem FileSystem;
private static bool _restartOnShutdown;
/// <summary> /// <summary>
/// Defines the entry point of the application. /// Defines the entry point of the application.
@ -71,9 +73,12 @@ namespace MediaBrowser.ServerApplication
SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_sqlite3()); SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_sqlite3());
var appPaths = CreateApplicationPaths(ApplicationPath, IsRunningAsService); var appPaths = CreateApplicationPaths(ApplicationPath, IsRunningAsService);
_appPaths = appPaths;
using (var logManager = new SimpleLogManager(appPaths.LogDirectoryPath, "server")) using (var logManager = new SimpleLogManager(appPaths.LogDirectoryPath, "server"))
{ {
_logManager = logManager;
logManager.ReloadLogger(LogSeverity.Debug); logManager.ReloadLogger(LogSeverity.Debug);
logManager.AddConsoleOutput(); logManager.AddConsoleOutput();
@ -129,17 +134,28 @@ namespace MediaBrowser.ServerApplication
return; return;
} }
try RunApplication(appPaths, logManager, IsRunningAsService, options);
logger.Info("Shutdown complete");
if (_restartOnShutdown)
{ {
RunApplication(appPaths, logManager, IsRunningAsService, options); logger.Info("Starting new server process");
} var restartCommandLine = GetRestartCommandLine();
finally
{ Process.Start(restartCommandLine.Item1, restartCommandLine.Item2);
OnServiceShutdown();
} }
} }
} }
public static Tuple<string, string> GetRestartCommandLine()
{
var currentProcess = Process.GetCurrentProcess();
var processModulePath = currentProcess.MainModule.FileName;
return new Tuple<string, string>(processModulePath, Environment.CommandLine);
}
/// <summary> /// <summary>
/// Determines whether [is already running] [the specified current process]. /// Determines whether [is already running] [the specified current process].
/// </summary> /// </summary>
@ -314,7 +330,7 @@ namespace MediaBrowser.ServerApplication
FileSystem = fileSystem; FileSystem = fileSystem;
_appHost = new WindowsAppHost(appPaths, using (var appHost = new WindowsAppHost(appPaths,
logManager, logManager,
options, options,
fileSystem, fileSystem,
@ -323,60 +339,59 @@ namespace MediaBrowser.ServerApplication
environmentInfo, environmentInfo,
new NullImageEncoder(), new NullImageEncoder(),
new SystemEvents(logManager.GetLogger("SystemEvents")), new SystemEvents(logManager.GetLogger("SystemEvents")),
new Networking.NetworkManager(logManager.GetLogger("NetworkManager"))); new Networking.NetworkManager(logManager.GetLogger("NetworkManager"))))
var initProgress = new Progress<double>();
if (!runService)
{ {
if (!options.ContainsOption("-nosplash")) ShowSplashScreen(_appHost.ApplicationVersion, initProgress, logManager.GetLogger("Splash")); var initProgress = new Progress<double>();
// Not crazy about this but it's the only way to suppress ffmpeg crash dialog boxes if (!runService)
SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOALIGNMENTFAULTEXCEPT | {
ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX); if (!options.ContainsOption("-nosplash")) ShowSplashScreen(appHost.ApplicationVersion, initProgress, logManager.GetLogger("Splash"));
}
var task = _appHost.Init(initProgress); // Not crazy about this but it's the only way to suppress ffmpeg crash dialog boxes
Task.WaitAll(task); SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOALIGNMENTFAULTEXCEPT |
ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX);
}
if (!runService) var task = appHost.Init(initProgress);
{
task = InstallVcredist2013IfNeeded(_appHost, _logger);
Task.WaitAll(task); Task.WaitAll(task);
// needed by skia if (!runService)
task = InstallVcredist2015IfNeeded(_appHost, _logger); {
Task.WaitAll(task); task = InstallVcredist2013IfNeeded(appHost.HttpClient, _logger);
} Task.WaitAll(task);
// set image encoder here // needed by skia
_appHost.ImageProcessor.ImageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => _appHost.HttpClient, appPaths); task = InstallVcredist2015IfNeeded(appHost.HttpClient, _logger);
Task.WaitAll(task);
}
task = task.ContinueWith(new Action<Task>(a => _appHost.RunStartupTasks()), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent); // set image encoder here
appHost.ImageProcessor.ImageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => appHost.HttpClient, appPaths);
if (runService) task = task.ContinueWith(new Action<Task>(a => appHost.RunStartupTasks()), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent);
{
StartService(logManager);
}
else
{
Task.WaitAll(task);
Microsoft.Win32.SystemEvents.SessionSwitch += SystemEvents_SessionSwitch; if (runService)
{
StartService(logManager);
}
else
{
Task.WaitAll(task);
HideSplashScreen(); HideSplashScreen();
ShowTrayIcon(); ShowTrayIcon(appHost);
}
} }
} }
private static ServerNotifyIcon _serverNotifyIcon; private static ServerNotifyIcon _serverNotifyIcon;
private static TaskScheduler _mainTaskScheduler; private static TaskScheduler _mainTaskScheduler;
private static void ShowTrayIcon() private static void ShowTrayIcon(ApplicationHost appHost)
{ {
//Application.EnableVisualStyles(); //Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false); //Application.SetCompatibleTextRenderingDefault(false);
_serverNotifyIcon = new ServerNotifyIcon(_appHost.LogManager, _appHost, _appHost.ServerConfigurationManager, _appHost.LocalizationManager); _serverNotifyIcon = new ServerNotifyIcon(appHost.LogManager, appHost, appHost.ServerConfigurationManager, appHost.LocalizationManager);
_mainTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); _mainTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Application.Run(); Application.Run();
} }
@ -413,14 +428,6 @@ namespace MediaBrowser.ServerApplication
} }
} }
static void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
{
if (e.Reason == SessionSwitchReason.SessionLogon)
{
BrowserLauncher.OpenDashboard(_appHost);
}
}
public static void Invoke(Action action) public static void Invoke(Action action)
{ {
if (IsRunningAsService) if (IsRunningAsService)
@ -452,14 +459,6 @@ namespace MediaBrowser.ServerApplication
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
static void service_Disposed(object sender, EventArgs e) static void service_Disposed(object sender, EventArgs e)
{ {
OnServiceShutdown();
}
private static void OnServiceShutdown()
{
_logger.Info("Shutting down");
DisposeAppHost();
} }
/// <summary> /// <summary>
@ -562,7 +561,7 @@ namespace MediaBrowser.ServerApplication
{ {
var exception = (Exception)e.ExceptionObject; var exception = (Exception)e.ExceptionObject;
new UnhandledExceptionWriter(_appHost.ServerConfigurationManager.ApplicationPaths, _logger, _appHost.LogManager, FileSystem, new ConsoleLogger()).Log(exception); new UnhandledExceptionWriter(_appPaths, _logger, _logManager, FileSystem, new ConsoleLogger()).Log(exception);
if (!IsRunningAsService) if (!IsRunningAsService)
{ {
@ -623,45 +622,22 @@ namespace MediaBrowser.ServerApplication
} }
else else
{ {
DisposeAppHost();
ShutdownWindowsApplication(); ShutdownWindowsApplication();
} }
} }
public static void Restart() public static void Restart()
{ {
DisposeAppHost();
if (IsRunningAsService) if (IsRunningAsService)
{ {
RestartWindowsService();
} }
else else
{ {
//_logger.Info("Hiding server notify icon"); _restartOnShutdown = true;
//_serverNotifyIcon.Visible = false;
_logger.Info("Starting new instance");
//Application.Restart();
Process.Start(ApplicationPath);
ShutdownWindowsApplication(); ShutdownWindowsApplication();
} }
} }
private static void DisposeAppHost()
{
if (!_appHostDisposed)
{
_logger.Info("Disposing app host");
_appHostDisposed = true;
_appHost.Dispose();
_logger.Info("App host dispose complete");
}
}
private static void ShutdownWindowsApplication() private static void ShutdownWindowsApplication()
{ {
if (_serverNotifyIcon != null) if (_serverNotifyIcon != null)
@ -671,9 +647,7 @@ namespace MediaBrowser.ServerApplication
} }
_logger.Info("Calling Application.Exit"); _logger.Info("Calling Application.Exit");
//Application.Exit(); Application.Exit();
Environment.Exit(0);
} }
private static void ShutdownWindowsService() private static void ShutdownWindowsService()
@ -689,23 +663,7 @@ namespace MediaBrowser.ServerApplication
} }
} }
private static void RestartWindowsService() private static async Task InstallVcredist2013IfNeeded(IHttpClient httpClient, ILogger logger)
{
_logger.Info("Restarting background service");
var startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
Verb = "runas",
ErrorDialog = false,
Arguments = String.Format("/c sc stop {0} & sc start {0} & sc start {0}", BackgroundService.GetExistingServiceName())
};
Process.Start(startInfo);
}
private static async Task InstallVcredist2013IfNeeded(ApplicationHost appHost, ILogger logger)
{ {
// Reference // Reference
// http://stackoverflow.com/questions/12206314/detect-if-visual-c-redistributable-for-visual-studio-2012-is-installed // http://stackoverflow.com/questions/12206314/detect-if-visual-c-redistributable-for-visual-studio-2012-is-installed
@ -737,7 +695,7 @@ namespace MediaBrowser.ServerApplication
try try
{ {
await InstallVcredist(GetVcredist2013Url()).ConfigureAwait(false); await InstallVcredist(GetVcredist2013Url(), httpClient).ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -757,7 +715,7 @@ namespace MediaBrowser.ServerApplication
return "https://github.com/MediaBrowser/Emby.Resources/raw/master/vcredist2013/vcredist_x86.exe"; return "https://github.com/MediaBrowser/Emby.Resources/raw/master/vcredist2013/vcredist_x86.exe";
} }
private static async Task InstallVcredist2015IfNeeded(ApplicationHost appHost, ILogger logger) private static async Task InstallVcredist2015IfNeeded(IHttpClient httpClient, ILogger logger)
{ {
// Reference // Reference
// http://stackoverflow.com/questions/12206314/detect-if-visual-c-redistributable-for-visual-studio-2012-is-installed // http://stackoverflow.com/questions/12206314/detect-if-visual-c-redistributable-for-visual-studio-2012-is-installed
@ -813,7 +771,7 @@ namespace MediaBrowser.ServerApplication
try try
{ {
await InstallVcredist(GetVcredist2015Url()).ConfigureAwait(false); await InstallVcredist(GetVcredist2015Url(), httpClient).ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -833,10 +791,8 @@ namespace MediaBrowser.ServerApplication
return "https://github.com/MediaBrowser/Emby.Resources/raw/master/vcredist2015/vc_redist.x86.exe"; return "https://github.com/MediaBrowser/Emby.Resources/raw/master/vcredist2015/vc_redist.x86.exe";
} }
private async static Task InstallVcredist(string url) private async static Task InstallVcredist(string url, IHttpClient httpClient)
{ {
var httpClient = _appHost.HttpClient;
var tmp = await httpClient.GetTempFile(new HttpRequestOptions var tmp = await httpClient.GetTempFile(new HttpRequestOptions
{ {
Url = url, Url = url,

View file

@ -1,3 +1,3 @@
using System.Reflection; using System.Reflection;
[assembly: AssemblyVersion("3.2.30.10")] [assembly: AssemblyVersion("3.2.30.11")]