dotnet/wpf · error · InvalidOperationException

SR.HwndTarget_HardwareNotSupportDueToProtocolMismatch

Error message

SR.HwndTarget_HardwareNotSupportDueToProtocolMismatch

What it means

When the process was forced into software rendering (MediaSystem.ForceSoftwareRendering, typically due to a remote-session/protocol mismatch such as RDP without hardware support), setting HwndTarget.RenderMode to Hardware or HardwareReference throws InvalidOperationException (SR.HwndTarget_HardwareNotSupportDueToProtocolMismatch). The request directly contradicts the effective rendering pipeline.

Solutions

  1. Set RenderMode.Default or RenderMode.SoftwareOnly instead of Hardware in remote-session scenarios
  2. Detect the remote session (SystemParameters.ClientAreaAnimation / GetSystemMetrics(SM_REMOTESESSION)) and skip forcing hardware
  3. Remove ForceSoftwareRendering configuration if hardware is genuinely available and required

Example fix

// before
HwndTarget.RenderMode = RenderMode.Hardware; // throws under RDP
// after
bool remote = NativeMethods.GetSystemMetrics(0x1000) != 0;
HwndTarget.RenderMode = remote ? RenderMode.SoftwareOnly : RenderMode.Default;
Defensive patterns

Strategy: validation

Validate before calling

if (MediaSystem.ForceSoftwareRendering && mode is RenderingMode.Hardware or RenderingMode.HardwareReference)
    mode = RenderingMode.Default;

Type guard

bool IsAssignable(RenderMode m) => m is RenderingMode.Default or RenderingMode.SoftwareOnly;

Try / catch

try { HwndTarget.RenderMode = mode; } catch (InvalidOperationException) { HwndTarget.RenderMode = RenderMode.SoftwareOnly; }

Prevention

When it happens

Trigger: Assigning RenderMode = RenderMode.Hardware (or HardwareReference) while the app is running under a remote session that disabled hardware rendering.

Common situations: Apps deployed over RDP/Citrix that hard-code hardware rendering; regression when testing inside remote desktop sessions after working on physical machines.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/86962a2a46a21b5e. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/InterOp/HwndTarget.cs:591

            IntPtr hwnd
            );

        internal void InvalidateRenderMode()
        {
            RenderingMode mode =
                RenderMode == RenderMode.SoftwareOnly ? RenderingMode.Software : RenderingMode.Default;

            //
            // If ForceSoftwareRendering is set then the transport is connected to a client (magnifier) that cannot
            // handle our transport protocol version. Therefore we force software rendering so that the rendered
            // content is available through NTUser redirection. If software is not allowed an exception is thrown.
            //
            if (MediaSystem.ForceSoftwareRendering)
            {
                if (mode == RenderingMode.Hardware ||
                    mode == RenderingMode.HardwareReference)
                {
                    throw new InvalidOperationException(SR.HwndTarget_HardwareNotSupportDueToProtocolMismatch);
                }
                else
                {
                    Debug.Assert(mode == RenderingMode.Software || mode == RenderingMode.Default);
                    // If the mode is default we can chose what works. When we have a mismatched transport protocol version
                    // we need to fallback to software rendering.
                    mode = RenderingMode.Software;
                }
            }

            //Obtain compatibility flags set in the application
            bool? enableMultiMonitorDisplayClipping =
                System.Windows.CoreCompatibilityPreferences.EnableMultiMonitorDisplayClipping;

            if (enableMultiMonitorDisplayClipping != null)
            {
                // The flag is explicitly set by the user in application manifest
                mode |= RenderingMode.IsDisableMultimonDisplayClippingValid;

View on GitHub (pinned to 81131a70a4)