dotnet/wpf · error · InvalidOperationException

SR.HwndTarget_WindowAlreadyHasContent

Error message

SR.HwndTarget_WindowAlreadyHasContent

What it means

After VisualTarget_AttachToHwnd returns E_ACCESSDENIED (0x80070005), HwndTarget translates that HRESULT into InvalidOperationException (SR.HwndTarget_WindowAlreadyHasContent). It means the Win32 window already has another rendering target attached, and a window can host only one HwndTarget's composition content.

Solutions

  1. Use a fresh child HWND (e.g. via HwndHost) for the new HwndSource instead of the window that already has content
  2. Add the content to the existing WPF visual tree rather than interop-attaching to the same hwnd
  3. Ensure the previous HwndSource on that hwnd is disposed before creating a new one

Example fix

// before
var s2 = HwndSource.FromHwnd(existingWpfWindowHwnd); // E_ACCESSDENIED -> throws
// after
var host = new HwndHost();
existingPanel.Children.Add(host); // host renders into its own child hwnd
Defensive patterns

Strategy: validation

Validate before calling

if (HwndSource.FromHwnd(hwnd) != null) throw new InvalidOperationException("window already hosts WPF content");

Try / catch

try { new HwndSource(...); } catch (InvalidOperationException) { /* reuse existing source or attach to a child hwnd */ }

Prevention

When it happens

Trigger: Creating a second HwndSource (or calling HwndSource.FromHwnd) on an HWND that already has WPF content; attaching to a WPF Window's own hwnd from custom code.

Common situations: Trying to host WPF content inside an existing WPF window via interop instead of adding it to the visual tree; re-parenting an HwndSource onto a window that already has one.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

                    SR.HwndTarget_InvalidWindowProcess,
                    nameof(hwnd)
                    );
            }
            else if (threadId != SafeNativeMethods.GetCurrentThreadId())
            {
                throw new ArgumentException(
                    SR.HwndTarget_InvalidWindowThread,
                    nameof(hwnd)
                    );
            }

            int hr = VisualTarget_AttachToHwnd(hwnd);

            if (HRESULT.Failed(hr))
            {
                if (hr == unchecked((int)0x80070005)) // E_ACCESSDENIED
                {
                    throw new InvalidOperationException(
                        SR.HwndTarget_WindowAlreadyHasContent
                        );
                }
                else
                {
                    HRESULT.Check(hr);
                }
            }

            EnsureNotificationWindow();
            _notificationWindowHelper.AttachHwndTarget(this);
            UnsafeNativeMethods.WTSRegisterSessionNotification(hwnd, NativeMethods.NOTIFY_FOR_THIS_SESSION);
        }

        [DllImport(DllImport.MilCore, EntryPoint = "MilVisualTarget_AttachToHwnd")]
        internal static extern int VisualTarget_AttachToHwnd(
            IntPtr hwnd
            );

View on GitHub (pinned to 81131a70a4)