internal static bool OnException(System.Exception e, bool isTerminating) { ExceptionReporting?.Invoke(e, EventArgs.Empty); var proc = Process.GetCurrentProcess(); bool fromSTA = true; //avoid recursive reporting when IsTerminating is true, since we have registered both Main Form and AppDomain with unhandled exceptions if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA) { if (_previousException != null && e != null && _previousException.ToString() == e.ToString()) { ReportLogger.LogInfo(new ArgumentException("Trying to report on the same exception.", e).ToString()); //same as previous return(_tryContinueAfterException); } _previousException = e; } ReportLogger.LogInfo("Received exception (isTerminating = " + isTerminating + ")"); TheException = e; try { //use ExceptionRegistrator.UseReportGUI to control if UI is to be used or not. if (!useReportGUI) { ReportExceptionWithNoGUI(Reporter, Version, ApplicationName, e); return(false); } // XAML issue with MTA threads. if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) { LogToFile(e); ReportInSTA(e, isTerminating); fromSTA = false; return(_tryContinueAfterException); } //only report one exception at the time. lock (_syncObject) { string errorText = CreateExceptionText(e); //show the error to the user and collect a description of the error from the user. try { //show the exception using the registered IReportForm. //if return value is false -> cancel if (!_form.ShowException(errorText, //this callback is to be used when the form click on the Send button. DoPost)) { //cancel report exception to log LogToFile(e); } } catch (System.Exception ex) { //log report exception var report = new TFSExceptionReport(ApplicationName, Reporter, Reporter, e, Version, "THIS IS A AUTO GENERATED TEXT: Failed to show exception report."); ReportLogger.LogToFile(report); ReportLogger.LogExceptionsDuringDelivery( new InvalidOperationException("Failed to show exception report.", ex)); } } } catch (ThreadAbortException terminate) { try { _form.Window.Close(); } catch { //ignore... } ReportLogger.LogInfo(new ThreadStateException("Report form is terminating.", terminate).ToString()); } finally { //we should inform the user that the application is about to terminate. // currently only support for WPF. if (_showExitAppWindow && isTerminating && fromSTA && Application.Current != null) { try { var terminateWindow = new IsTerminatingWindow(); terminateWindow.Topmost = true; terminateWindow.Show(); //sleep for 5000 seconds. Thread.Sleep(5000); terminateWindow.Close(); } catch { //for now ignore ... this will happen if thread is MTA...but no more time to code. } } } return(_tryContinueAfterException); }