using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Constants; using MediaBrowser.Common.Implementations.Updates; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Implementations; using MediaBrowser.ServerApplication.Splash; using Microsoft.Win32; using System; using System.Diagnostics; using System.IO; using System.Net.Cache; using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Imaging; namespace MediaBrowser.ServerApplication { /// /// Interaction logic for App.xaml /// public partial class App : Application { /// /// The single instance mutex /// private static Mutex _singleInstanceMutex; /// /// Defines the entry point of the application. /// [STAThread] public static void Main() { bool createdNew; var runningPath = Process.GetCurrentProcess().MainModule.FileName.Replace(Path.DirectorySeparatorChar.ToString(), string.Empty); _singleInstanceMutex = new Mutex(true, @"Local\" + runningPath, out createdNew); if (!createdNew) { _singleInstanceMutex = null; return; } // Look for the existence of an update archive var appPaths = new ServerApplicationPaths(); var updateArchive = Path.Combine(appPaths.TempUpdatePath, Constants.MbServerPkgName + ".zip"); if (File.Exists(updateArchive)) { // Update is there - execute update try { new ApplicationUpdater().UpdateApplication(MBApplication.MBServer, appPaths, updateArchive); // And just let the app exit so it can update return; } catch (Exception e) { MessageBox.Show(string.Format("Error attempting to update application.\n\n{0}\n\n{1}", e.GetType().Name, e.Message)); } } var application = new App(); application.Run(); } /// /// Gets the instance. /// /// The instance. public static App Instance { get { return Current as App; } } /// /// Gets or sets the logger. /// /// The logger. protected ILogger Logger { get; set; } /// /// Gets or sets the composition root. /// /// The composition root. protected ApplicationHost CompositionRoot { get; set; } /// /// Initializes a new instance of the class. /// /// The logger. public App() { InitializeComponent(); } /// /// Gets the name of the uninstaller file. /// /// The name of the uninstaller file. protected string UninstallerFileName { get { return "MediaBrowser.Server.Uninstall.exe"; } } /// /// Raises the event. /// /// A that contains the event data. protected override void OnStartup(StartupEventArgs e) { AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; LoadKernel(); SystemEvents.SessionEnding += SystemEvents_SessionEnding; } /// /// Handles the UnhandledException event of the CurrentDomain control. /// /// The source of the event. /// The instance containing the event data. void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { var exception = (Exception)e.ExceptionObject; Logger.ErrorException("UnhandledException", exception); MessageBox.Show("Unhandled exception: " + exception.Message); if (!Debugger.IsAttached) { Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(exception)); } } /// /// Handles the SessionEnding event of the SystemEvents control. /// /// The source of the event. /// The instance containing the event data. void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e) { // Try to shut down gracefully Shutdown(); } /// /// Loads the kernel. /// protected async void LoadKernel() { try { CompositionRoot = new ApplicationHost(); Logger = CompositionRoot.LogManager.GetLogger("App"); var splash = new SplashWindow(CompositionRoot.ApplicationVersion); splash.Show(); await CompositionRoot.Init(); splash.Hide(); var task = CompositionRoot.RunStartupTasks(); new MainWindow(CompositionRoot.LogManager, CompositionRoot, CompositionRoot.ServerConfigurationManager, CompositionRoot.UserManager, CompositionRoot.LibraryManager, CompositionRoot.JsonSerializer, CompositionRoot.DisplayPreferencesRepository).Show(); await task.ConfigureAwait(false); } 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); } } /// /// Raises the event. /// /// An that contains the event data. protected override void OnExit(ExitEventArgs e) { ReleaseMutex(); base.OnExit(e); if (CompositionRoot != null) { CompositionRoot.Dispose(); } } /// /// Releases the mutex. /// private void ReleaseMutex() { if (_singleInstanceMutex == null) { return; } _singleInstanceMutex.ReleaseMutex(); _singleInstanceMutex.Close(); _singleInstanceMutex.Dispose(); _singleInstanceMutex = null; } /// /// Opens the dashboard page. /// /// The page. /// The logged in user. /// The configuration manager. /// The app host. public static void OpenDashboardPage(string page, User loggedInUser, IServerConfigurationManager configurationManager, IServerApplicationHost appHost) { var url = "http://localhost:" + configurationManager.Configuration.HttpServerPortNumber + "/" + appHost.WebApplicationName + "/dashboard/" + page; OpenUrl(url); } /// /// Opens the URL. /// /// The URL. public static void OpenUrl(string url) { var process = new Process { StartInfo = new ProcessStartInfo { FileName = url }, EnableRaisingEvents = true }; process.Exited += ProcessExited; try { process.Start(); } catch (Exception ex) { MessageBox.Show("There was an error launching your web browser. Please check your defualt browser settings."); } } /// /// Processes the exited. /// /// The sender. /// The instance containing the event data. static void ProcessExited(object sender, EventArgs e) { ((Process)sender).Dispose(); } /// /// Restarts this instance. /// /// public void Restart() { Dispatcher.Invoke(ReleaseMutex); CompositionRoot.Dispose(); System.Windows.Forms.Application.Restart(); Dispatcher.Invoke(Shutdown); } /// /// Gets the image. /// /// The URI. /// Image. /// uri public Image GetImage(string uri) { if (string.IsNullOrEmpty(uri)) { throw new ArgumentNullException("uri"); } return GetImage(new Uri(uri)); } /// /// Gets the image. /// /// The URI. /// Image. /// uri public Image GetImage(Uri uri) { if (uri == null) { throw new ArgumentNullException("uri"); } return new Image { Source = GetBitmapImage(uri) }; } /// /// Gets the bitmap image. /// /// The URI. /// BitmapImage. /// uri public BitmapImage GetBitmapImage(string uri) { if (string.IsNullOrEmpty(uri)) { throw new ArgumentNullException("uri"); } return GetBitmapImage(new Uri(uri)); } /// /// Gets the bitmap image. /// /// The URI. /// BitmapImage. /// uri 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; } } }