/ src / modules / launcher / PowerLauncher / Helper / ErrorReporting.cs
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  }