using Sarand.PatientMgr.Core.App; using Sarand.Core.App; using Sarand.Core.Base; using Sarand.PatientMgr.App.Forms; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; using Sarand.PatientMgr.Win.Forms.App; namespace Sarand.PatientMgr.App { //======================================================================= static class Program { //------------------------------------------------------------------- // Definitions. [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern bool SetProcessDPIAware (); //------------------------------------------------------------------- // Data members. private static Form mainForm = null; //------------------------------------------------------------------- /// The main entry point for the application. [STAThread] static void Main (string[] args) { bool runningProcesses = false; try { // Parse command line. SacsCommandLineInfo CmdLineInfo = new SacsCommandLineInfo(args); bool runProcesses = (CmdLineInfo.ProcessDefinitions.Count > 0); // PatientMgr Application. String logMessageSuffix = (runProcesses ? " [auto]" : ""); using (var app = new SaPatientMgrApp(Spm.ApplicationCaption + " Start v" + Spm.Version + logMessageSuffix)) { // Check for startup error. if (app.HasErrorState()) { MessageBox.Show("Startup error: " + app.ErrorStateMessage, Spm.ApplicationCaption, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // Trap thread and unhandled exceptions. var threadExceptionHandler = new ThreadExceptionEventHandler(Application_ThreadException); Application.ThreadException += threadExceptionHandler; var unhandledExceptionHandler = new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); AppDomain.CurrentDomain.UnhandledException += unhandledExceptionHandler; if (runProcesses) { // Run specified processes and close application. runningProcesses = true; /* foreach (SacsProcessDefinition processDfn in CmdLineInfo.ProcessDefinitions) SpmProcessConsole.InvokeProcessDefinition(app.SessionContext, processDfn, app.UserContext.DbUpdateInfo); */ } else { // Configure application. SetProcessDPIAware(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // Main form. SaPatientMgrForm.Config configMainForm = new SaPatientMgrForm.Config(); using (Form form = new SaPatientMgrForm(configMainForm)) { mainForm = form; Application.Run(form); mainForm = null; } Application.ThreadException -= threadExceptionHandler; Logger.Info(Spm.ApplicationCaption + " End" + logMessageSuffix, true); } } } catch (Exception exc) { String exceptionName = exc.GetType().Name + (exc.InnerException != null ? " (" + exc.InnerException.GetType().Name + ")" : ""); if (!runningProcesses) MessageBox.Show(exceptionName + " encountered:\n\n" + exc.Message + "\n\nApplication will close."); Logger.Warn(exceptionName + ": " + exc.Message + exc.GetStackEntries(6).Concat("", "\n\t"), true); } finally { Application.Exit(); } } //------------------------------------------------------------------- // Trap thread exceptions. // Ref: https://stackoverflow.com/questions/36014/why-is-net-exception-not-caught-by-try-catch-block // See: References to Application.ThreadException above. public class ThreadException : Exception { public ThreadException (String message, Exception innerException) : base(message, innerException) { } } public static void Application_ThreadException (object sender, ThreadExceptionEventArgs e) { Exception exc = e.Exception; Logger.Error("Application_ThreadException " + exc.GetType().Name + ": " + exc.Message + ExceptionUtil.GetStackEntries(exc, 20).Concat("", "\n\t"), true); if (!SacsSystem.DebugMode) { // Throw on main thread. if (mainForm != null && mainForm.InvokeRequired) mainForm.Invoke((MethodInvoker)delegate { throw exc; }); else throw exc; // new ThreadException(exc.Message, exc); } } //------------------------------------------------------------------- // Trap unhandled exceptions. // Ref: https://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception(v=vs.110).aspx // See: References to Application.ThreadException above. public class UnhandledException : Exception { public UnhandledException (String message, Exception innerException) : base(message, innerException) { } } public static void CurrentDomain_UnhandledException (object sender, UnhandledExceptionEventArgs e) { Exception exc = e.ExceptionObject as Exception; Logger.Error("CurrentDomain_UnhandledException " + exc.GetType().Name + ": " + exc.Message + ExceptionUtil.GetStackEntries(exc, 20).Concat("", "\n\t")); if (!SacsSystem.DebugMode) { // Throw on main thread. if (mainForm != null && mainForm.InvokeRequired) mainForm.Invoke((MethodInvoker)delegate { throw exc; }); else throw exc; // new UnhandledException(exc.ToString(), exc); } } //------------------------------------------------------------------- } //======================================================================= }