using System; using System.IO; using System.Reflection; using System.Threading; using System.Windows.Forms; using OnTopReplica.Properties; using OnTopReplica.StartupOptions; using OnTopReplica.Update; namespace OnTopReplica { static class Program { public static PlatformSupport Platform { get; private set; } public static UpdateManager Update { get; private set; } static MainForm _mainForm; /// /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { try { AppPaths.SetupPaths(); } catch (Exception ex) { MessageBox.Show(string.Format("Unable to setup application folders: {0}", ex), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } Log.Write("Launching OnTopReplica v.{0}", Application.ProductVersion); //Hook fatal abort handler AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); //Initialize and check for platform support Platform = PlatformSupport.Create(); if (!Platform.CheckCompatibility()) return; Platform.PreHandleFormInit(); Log.Write("Platform support initialized"); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //Update settings if needed if (Settings.Default.MustUpdate) { Settings.Default.Upgrade(); Settings.Default.MustUpdate = false; } //Load startup options var options = StartupOptions.Factory.CreateOptions(args); string optionsMessage = options.DebugMessage; if (!string.IsNullOrEmpty(optionsMessage)) { //show dialog if debug message present or if parsing failed var dlg = new CommandLineReportForm(options.Status, optionsMessage); dlg.ShowDialog(); } if (options.Status == CliStatus.Information || options.Status == CliStatus.Error) return; //Load language Thread.CurrentThread.CurrentUICulture = Settings.Default.Language; //Show form using (_mainForm = new MainForm(options)) { Application.Idle += _handlerIdleUpdater; //Enter GUI loop Application.Run(_mainForm); //Re-enable chrome to store correct position (position is stored always WITH chrome: when restoring fails, the position stays ok) Settings.Default.RestoreLastShowChrome = _mainForm.IsChromeVisible; if (!_mainForm.IsChromeVisible) _mainForm.IsChromeVisible = true; //Persist settings Log.Write("Last position before shutdown: {0}, size: {1}", _mainForm.Location, _mainForm.Size); Settings.Default.RestoreLastPosition = _mainForm.Location; Settings.Default.RestoreLastSize = _mainForm.ClientSize; Settings.Default.Save(); //Store last thumbnail, if any if (_mainForm.ThumbnailPanel.IsShowingThumbnail && _mainForm.CurrentThumbnailWindowHandle != null) { Settings.Default.RestoreLastWindowTitle = _mainForm.CurrentThumbnailWindowHandle.Title; Settings.Default.RestoreLastWindowHwnd = _mainForm.CurrentThumbnailWindowHandle.Handle.ToInt64(); Settings.Default.RestoreLastWindowClass = _mainForm.CurrentThumbnailWindowHandle.Class; } else { Settings.Default.RestoreLastWindowTitle = string.Empty; Settings.Default.RestoreLastWindowHwnd = 0; Settings.Default.RestoreLastWindowClass = string.Empty; } } } private static EventHandler _handlerIdleUpdater = new EventHandler(Application_Idle); /// /// Callback detecting application idle time. /// static void Application_Idle(object sender, EventArgs e) { Application.Idle -= _handlerIdleUpdater; Update = new UpdateManager(_mainForm); Update.UpdateCheckCompleted += new EventHandler(UpdateManager_CheckCompleted); Update.CheckForUpdate(); } /// /// Callback that handles update checking. /// static void UpdateManager_CheckCompleted(object sender, UpdateCheckCompletedEventArgs e) { if (e.Success && e.Information != null) { Log.Write("Updated check successful (latest version is {0})", e.Information.LatestVersion); if (e.Information.IsNewVersion) { Update.ConfirmAndInstall(); } } else { Log.WriteException("Unable to check for updates", e.Error); } } static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Log.WriteException("Unhandled exception", e.ExceptionObject as Exception); string path = AppPaths.GenerateCrashDumpPath(); using (var s = new FileStream(path, FileMode.Create)) { using (var sw = new StreamWriter(s)) { sw.WriteLine("OnTopReplica Dump file"); sw.WriteLine("This file has been created because OnTopReplica crashed."); sw.WriteLine("Please send it to lck@klopfenstein.net to help fix the bug that caused the crash."); sw.WriteLine(); sw.WriteLine("Last exception:"); sw.WriteLine(e.ExceptionObject.ToString()); sw.WriteLine(); sw.WriteLine("OnTopReplica v.{0}", Application.ProductVersion); sw.WriteLine("OS: {0}", Environment.OSVersion.ToString()); sw.WriteLine(".NET: {0}", Environment.Version.ToString()); sw.WriteLine("DWM: {0}", WindowsFormsAero.OsSupport.IsCompositionEnabled); sw.WriteLine("Launch command: {0}", Environment.CommandLine); sw.WriteLine("UTC time: {0} {1}", DateTime.UtcNow.ToShortDateString(), DateTime.UtcNow.ToShortTimeString()); } } Log.Write("Crash dump written to {0}", path); } } }