Program.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. using MediaBrowser.Common.Constants;
  2. using MediaBrowser.Common.Implementations.Logging;
  3. using MediaBrowser.Common.Implementations.Updates;
  4. using MediaBrowser.Model.Logging;
  5. using MediaBrowser.Server.Implementations;
  6. using MediaBrowser.ServerApplication;
  7. using Microsoft.Win32;
  8. using System;
  9. using System.Diagnostics;
  10. using System.IO;
  11. using System.Threading;
  12. using System.Windows;
  13. using Gtk;
  14. using System.Threading.Tasks;
  15. namespace MediaBrowser.Server.Mono
  16. {
  17. public class MainClass
  18. {
  19. private static ApplicationHost _appHost;
  20. private static Mutex _singleInstanceMutex;
  21. private static ILogger _logger;
  22. public static void Main (string[] args)
  23. {
  24. Application.Init ();
  25. var appPaths = CreateApplicationPaths();
  26. var logManager = new NlogManager(appPaths.LogDirectoryPath, "server");
  27. logManager.ReloadLogger(LogSeverity.Info);
  28. var logger = _logger = logManager.GetLogger("Main");
  29. BeginLog(logger);
  30. AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
  31. bool createdNew;
  32. var runningPath = Process.GetCurrentProcess().MainModule.FileName.Replace(Path.DirectorySeparatorChar.ToString(), string.Empty);
  33. _singleInstanceMutex = new Mutex(true, @"Local\" + runningPath, out createdNew);
  34. if (!createdNew)
  35. {
  36. _singleInstanceMutex = null;
  37. logger.Info("Shutting down because another instance of Media Browser Server is already running.");
  38. return;
  39. }
  40. if (PerformUpdateIfNeeded(appPaths, logger))
  41. {
  42. logger.Info("Exiting to perform application update.");
  43. return;
  44. }
  45. try
  46. {
  47. RunApplication(appPaths, logManager);
  48. }
  49. finally
  50. {
  51. logger.Info("Shutting down");
  52. ReleaseMutex(logger);
  53. _appHost.Dispose();
  54. }
  55. }
  56. private static ServerApplicationPaths CreateApplicationPaths()
  57. {
  58. return new ServerApplicationPaths("D:\\MonoTest");
  59. }
  60. private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager)
  61. {
  62. // TODO: Show splash here
  63. SystemEvents.SessionEnding += SystemEvents_SessionEnding;
  64. _appHost = new ApplicationHost(appPaths, logManager);
  65. var task = _appHost.Init();
  66. Task.WaitAll (task);
  67. task = _appHost.RunStartupTasks();
  68. Task.WaitAll (task);
  69. // TODO: Hide splash here
  70. MainWindow win = new MainWindow ();
  71. win.Show ();
  72. Application.Run ();
  73. }
  74. /// <summary>
  75. /// Handles the SessionEnding event of the SystemEvents control.
  76. /// </summary>
  77. /// <param name="sender">The source of the event.</param>
  78. /// <param name="e">The <see cref="SessionEndingEventArgs"/> instance containing the event data.</param>
  79. static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
  80. {
  81. if (e.Reason == SessionEndReasons.SystemShutdown)
  82. {
  83. Shutdown();
  84. }
  85. }
  86. /// <summary>
  87. /// Begins the log.
  88. /// </summary>
  89. /// <param name="logger">The logger.</param>
  90. private static void BeginLog(ILogger logger)
  91. {
  92. logger.Info("Media Browser Server started");
  93. logger.Info("Command line: {0}", string.Join(" ", Environment.GetCommandLineArgs()));
  94. logger.Info("Server: {0}", Environment.MachineName);
  95. logger.Info("Operating system: {0}", Environment.OSVersion.ToString());
  96. }
  97. /// <summary>
  98. /// Handles the UnhandledException event of the CurrentDomain control.
  99. /// </summary>
  100. /// <param name="sender">The source of the event.</param>
  101. /// <param name="e">The <see cref="UnhandledExceptionEventArgs"/> instance containing the event data.</param>
  102. static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
  103. {
  104. var exception = (Exception)e.ExceptionObject;
  105. _logger.ErrorException("UnhandledException", exception);
  106. if (!Debugger.IsAttached)
  107. {
  108. Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(exception));
  109. }
  110. }
  111. /// <summary>
  112. /// Releases the mutex.
  113. /// </summary>
  114. internal static void ReleaseMutex(ILogger logger)
  115. {
  116. if (_singleInstanceMutex == null)
  117. {
  118. return;
  119. }
  120. logger.Debug("Releasing mutex");
  121. _singleInstanceMutex.ReleaseMutex();
  122. _singleInstanceMutex.Close();
  123. _singleInstanceMutex.Dispose();
  124. _singleInstanceMutex = null;
  125. }
  126. /// <summary>
  127. /// Performs the update if needed.
  128. /// </summary>
  129. /// <param name="appPaths">The app paths.</param>
  130. /// <param name="logger">The logger.</param>
  131. /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
  132. private static bool PerformUpdateIfNeeded(ServerApplicationPaths appPaths, ILogger logger)
  133. {
  134. return false;
  135. }
  136. public static void Shutdown()
  137. {
  138. Application.Quit ();
  139. }
  140. public static void Restart()
  141. {
  142. // Second instance will start first, so release the mutex and dispose the http server ahead of time
  143. ReleaseMutex (_logger);
  144. _appHost.Dispose();
  145. Application.Quit ();
  146. }
  147. }
  148. }