ErrorReporting.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Windows; 7 using System.Windows.Threading; 8 9 using NLog; 10 using Wox.Infrastructure.Exception; 11 using Wox.Plugin; 12 13 namespace PowerLauncher.Helper 14 { 15 public static class ErrorReporting 16 { 17 private const string LoggerName = "UnHandledException"; 18 19 public static void ShowMessageBox(string title, string message) 20 { 21 Application.Current.Dispatcher.Invoke(() => 22 { 23 MessageBox.Show(message, title); 24 }); 25 } 26 27 public static void UnhandledExceptionHandle(object sender, UnhandledExceptionEventArgs e) 28 { 29 // handle non-ui thread exceptions 30 System.Windows.Application.Current.Dispatcher.Invoke(() => 31 { 32 HandleException(e?.ExceptionObject as Exception, true); 33 }); 34 } 35 36 public static void DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) 37 { 38 if (e != null) 39 { 40 // handle ui thread exceptions 41 HandleException(e.Exception, false); 42 43 // prevent application exist, so the user can copy prompted error info 44 e.Handled = true; 45 } 46 } 47 48 public static string RuntimeInfo() 49 { 50 var info = $"\nVersion: {Constant.Version}" + 51 $"\nOS Version: {Environment.OSVersion.VersionString}" + 52 $"\nIntPtr Length: {IntPtr.Size}" + 53 $"\nx64: {Environment.Is64BitOperatingSystem}"; 54 return info; 55 } 56 57 private static void HandleException(Exception e, bool isNotUIThread) 58 { 59 // The crash occurs in PresentationFramework.dll, not necessarily when the Runner UI is visible, originating from this line: 60 // https://github.com/dotnet/wpf/blob/3439f20fb8c685af6d9247e8fd2978cac42e74ac/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Shell/WindowChromeWorker.cs#L1005 61 // Many bug reports because users see the "Report problem UI" after "the" crash with System.Runtime.InteropServices.COMException 0xD0000701 or 0x80263001. 62 // However, displaying this "Report problem UI" during WPF crashes, especially when DWM composition is changing, is not ideal; some users reported it hangs for up to a minute before the "Report problem UI" appears. 63 // This change modifies the behavior to log the exception instead of showing the "Report problem UI". 64 if (ExceptionHelper.IsRecoverableDwmCompositionException(e as System.Runtime.InteropServices.COMException)) 65 { 66 var logger = LogManager.GetLogger(LoggerName); 67 logger.Error($"From {(isNotUIThread ? "non" : string.Empty)} UI thread's exception: {ExceptionFormatter.FormatException(e)}"); 68 } 69 else 70 { 71 Report(e, isNotUIThread); 72 } 73 } 74 75 private static void Report(Exception e, bool waitForClose) 76 { 77 if (e != null) 78 { 79 var logger = LogManager.GetLogger(LoggerName); 80 logger.Fatal($"From {(waitForClose ? "non" : string.Empty)} UI thread's exception: {ExceptionFormatter.FormatException(e)}"); 81 82 var reportWindow = new ReportWindow(e); 83 84 if (waitForClose) 85 { 86 reportWindow.ShowDialog(); 87 } 88 else 89 { 90 reportWindow.Show(); 91 } 92 } 93 } 94 } 95 }