mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Handle recoverable DWM composition exceptions gracefully (#4113)
This commit is contained in:
parent
c6c413202c
commit
a773b51ada
2 changed files with 51 additions and 0 deletions
|
|
@ -16,6 +16,15 @@ public static class ErrorReporting
|
|||
var logger = LogManager.GetLogger(methodName);
|
||||
logger.Fatal(ExceptionFormatter.FormatExcpetion(e));
|
||||
if (silent) return;
|
||||
|
||||
// Workaround for issue https://github.com/Flow-Launcher/Flow.Launcher/issues/4016
|
||||
// The crash occurs in PresentationFramework.dll, not necessarily when the Runner UI is visible, originating from this line:
|
||||
// https://github.com/dotnet/wpf/blob/3439f20fb8c685af6d9247e8fd2978cac42e74ac/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Shell/WindowChromeWorker.cs#L1005
|
||||
// Many bug reports because users see the "Error report UI" after the crash with System.Runtime.InteropServices.COMException 0xD0000701 or 0x80263001.
|
||||
// However, displaying this "Error report 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 it appears.
|
||||
// This change modifies the behavior to log the exception instead of showing the "Error report UI".
|
||||
if (ExceptionHelper.IsRecoverableDwmCompositionException(e)) return;
|
||||
|
||||
var reportWindow = new ReportWindow(e);
|
||||
reportWindow.Show();
|
||||
}
|
||||
|
|
|
|||
42
Flow.Launcher/Helper/ExceptionHelper.cs
Normal file
42
Flow.Launcher/Helper/ExceptionHelper.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// This is a direct copy of the file at https://github.com/microsoft/PowerToys/blob/main/src/modules/launcher/PowerLauncher/Helper/ExceptionHelper.cs and adapted for flow.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Flow.Launcher.Helper;
|
||||
|
||||
internal static class ExceptionHelper
|
||||
{
|
||||
private const string PresentationFrameworkExceptionSource = "PresentationFramework";
|
||||
|
||||
private const int DWM_E_COMPOSITIONDISABLED = unchecked((int)0x80263001);
|
||||
|
||||
// HRESULT for NT STATUS STATUS_MESSAGE_LOST (0xC0000701 | 0x10000000 == 0xD0000701)
|
||||
private const int STATUS_MESSAGE_LOST_HR = unchecked((int)0xD0000701);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the exception is a recoverable DWM composition exception.
|
||||
/// </summary>
|
||||
internal static bool IsRecoverableDwmCompositionException(Exception exception)
|
||||
{
|
||||
if (exception is not COMException comException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (comException.HResult is DWM_E_COMPOSITIONDISABLED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (comException.HResult is STATUS_MESSAGE_LOST_HR && comException.Source == PresentationFrameworkExceptionSource)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for common DWM composition changed patterns in the stack trace
|
||||
var stackTrace = comException.StackTrace;
|
||||
return !string.IsNullOrEmpty(stackTrace) &&
|
||||
stackTrace.Contains("DwmCompositionChanged", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue