using System; using System.Threading; using System.Windows.Forms; using EveOPreview.Configuration; using EveOPreview.UI; namespace EveOPreview { static class Program { private static string MutexName = "EVE-O Preview Single Instance Mutex"; private static string ConfigParameterName = "--config:"; /// The main entry point for the application. [STAThread] static void Main(string[] args) { // The very usual Mutex-based single-instance screening // 'token' variable is used to store reference to the instance Mutex // during the app lifetime object token = Program.GetInstanceToken(); // If it was not possible to aquire the app token then another app instance is already running // Nothing to do here if (token == null) { return; } ExceptionHandler handler = new ExceptionHandler(); handler.SetupExceptionHandlers(); Program.InitializeWinFormsGui(); IApplicationController controller = Program.InitializeApplicationController(); Program.SetupApplicationConttroller(controller, Program.GetCustomConfigFile(args)); controller.Run(); } private static string GetCustomConfigFile(string[] args) { // Parse startup parameters // Simple approach is used because something like NParams would be an overkill here string configFile = null; foreach (string arg in args) { if ((arg.Length <= Program.ConfigParameterName.Length) || !arg.StartsWith(Program.ConfigParameterName, StringComparison.Ordinal)) { continue; } configFile = arg.Substring(Program.ConfigParameterName.Length); break; } if (string.IsNullOrEmpty(configFile)) { return ""; } // One more check to drop trailing " if ((configFile.Length > 3) && (configFile[0] == '"') && (configFile[configFile.Length - 1] == '"')) { configFile = configFile.Substring(1, configFile.Length - 2); } return configFile; } private static object GetInstanceToken() { // The code might look overcomplicated here for a single Mutex operation // Yet we had already experienced a Windows-level issue // where .NET finalizer theread was literally paralyzed by // a failed Mutex operation. That did lead to weird OutOfMemory // exceptions later try { Mutex mutex = Mutex.OpenExisting(Program.MutexName); // if that didn't fail then anotherinstance is already running return null; } catch (UnauthorizedAccessException) { return null; } catch (Exception) { Mutex token = new Mutex(true, Program.MutexName, out var result); return result ? token : null; } } private static void InitializeWinFormsGui() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); } private static IApplicationController InitializeApplicationController() { IIocContainer container = new LightInjectContainer(); // UI classes IApplicationController controller = new ApplicationController(container) .RegisterView() .RegisterView() .RegisterView() .RegisterInstance(new ApplicationContext()); // Application services controller.RegisterService() .RegisterService() .RegisterService() .RegisterService() .RegisterService() .RegisterInstance(new AppConfig()) .RegisterInstance(new ThumbnailConfig()); return controller; } private static void SetupApplicationConttroller(IApplicationController controller, string configFile) { controller.Create().ConfigFileName = configFile; } } }