Skip to content

WindowChromeWorker._ExtendGlassFrame causes COMException - Desktop composition is disabled #11440

@mw-ea

Description

@mw-ea

Description

WPF application, that is left running when user's Remote Desktop session is locked (due to inactivity timeout).
When user reconnects over Remote Desktop (application still running), we sometimes see this exception.

System.Runtime.InteropServices.COMException at Standard.NativeMethods.DwmExtendFrameIntoClientArea
{Desktop composition is disabled} The operation could not be completed because desktop composition is disabled. (0x80263001)

call stack of main thread:

|    System.Windows.Threading.Dispatcher.CatchException
|    System.Windows.Threading.ExceptionWrapper.TryCatchWhen
|    [Managed to Native Transition]
|    System.Windows.Shell.WindowChromeWorker._ExtendGlassFrame
|    System.Windows.Shell.WindowChromeWorker._UpdateFrameState
|    System.Windows.Shell.WindowChromeWorker._HandleDwmCompositionChanged
|    System.Windows.Shell.WindowChromeWorker._WndProc
|    System.Windows.Interop.HwndSource.PublicHooksFilterMessage
|    MS.Win32.HwndWrapper.WndProc
|    System.Windows.Threading.ExceptionWrapper.InternalRealCall
|    System.Windows.Threading.ExceptionWrapper.TryCatchWhen
|    System.Windows.Threading.Dispatcher.LegacyInvokeImpl
|    MS.Win32.HwndSubclass.SubclassWndProc
|    [Native to Managed Transition]
|    [Managed to Native Transition]
|    WPF Dispatcher (0)
|    System.Windows.Threading.Dispatcher.PushFrameImpl
...<our app code>

<our app code> can be as basic as the entry point -> System.Windows.Application.RunDispatcher,
or our application is showing its own dialog at the time, so there are
System.Windows.Threading.Dispatcher.PushFrameImpl + our app code that leads to that
before the _HandleDwmCompositionChanged,
...but ultimately the same WindowChromeWorker call stack at the point of exception.

From the source of WindowChromeWorker.cs, there is a check for DwmIsCompositionEnabled() before calling DwmExtendFrameIntoClientArea().

So seems odd that could then trigger a "Desktop composition is disabled" exception.
Is it a bug within WindowChromeWorker or the native methods it uses?
maybe a race or unreliable result from DwmIsCompositionEnabled in the case of remote desktop reconnect.

Reproduction Steps

Issue presents in different scenarios for some of our users. Have not been able to pin down steps nor reproduce myself.
Simplest case is having the application running when Remote Desktop is locked, then login again (over RDP) to unlock the session.

Expected behavior

no exception

Actual behavior

Getting exception

System.Runtime.InteropServices.COMException at Standard.NativeMethods.DwmExtendFrameIntoClientArea
{Desktop composition is disabled} The operation could not be completed because desktop composition is disabled. (0x80263001)

from System.Windows.Shell.WindowChromeWorker._ExtendGlassFrame call to DwmExtendFrameIntoClientArea

Regression?

No response

Known Workarounds

none

Impact

Crashes the application.

Configuration

.Net 8
Windows 11: Microsoft Windows NT 10.0.26200.0
x64

Other information

Application makes use of DirectX. We do handle device re-init during remote desktop reconnect. This part works, but seems just after this we can see the reported exception - even when there is no direct use of the DirectX device by the app (no content rendered through it at the time).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions