dotnet/wpf · error · ArgumentException

SR.HwndTarget_InvalidWindowHandle

Error message

SR.HwndTarget_InvalidWindowHandle

What it means

HwndTarget.AttachToHwnd validates the target window handle before attaching rendering to it. If GetWindowThreadProcessId ran but IsWindow reports the hwnd is no longer a valid window, it throws ArgumentException (SR.HwndTarget_InvalidWindowHandle) with parameter name 'hwnd'.

Solutions

  1. Verify the handle before passing it: call IsWindow(hwnd) and ensure it is nonzero and from a live process
  2. Re-acquire a fresh HWND from the host at attach time rather than caching one
  3. Check that the native host keeps the window alive for the lifetime of the HwndSource

Example fix

// before
var source = new HwndSource(0, 0, 0, 0, 0, "x", new IntPtr(0xDEADBEEF)); // throws
// after
if (!NativeMethods.IsWindow(hwnd)) throw new InvalidOperationException("host hwnd is gone");
var source = new HwndSource(0, 0, 0, 0, 0, "x", hwnd);
Defensive patterns

Strategy: validation

Validate before calling

if (!UnsafeNativeMethods.IsWindow(new HandleRef(null, hwnd))) throw new InvalidOperationException("HWND is not valid");

Type guard

bool IsValidHwnd(IntPtr hwnd) => hwnd != IntPtr.Zero && NativeMethods.IsWindow(hwnd);

Try / catch

try { new HwndSource(...); } catch (ArgumentException) { /* re-acquire fresh hwnd from host */ }

Prevention

When it happens

Trigger: Passing an hwnd from a destroyed window, a garbage/fake handle, or a handle whose owning process exited between obtaining it and constructing HwndTarget.

Common situations: Interop scenarios where the host app receives an HWND from native code or another process and immediately creates an HwndSource/HwndTarget over it; race conditions where the host window closes first.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

            Debug.Assert(normalizedHwnd.Handle != IntPtr.Zero);
            return normalizedHwnd;
        }

        /// <summary>
        /// AttachToHwnd
        /// </summary>
        private void AttachToHwnd(IntPtr hwnd)
        {
            int processId = 0;
            int threadId = UnsafeNativeMethods.GetWindowThreadProcessId(
                new HandleRef(this, hwnd),
                out processId
                );

            if (!UnsafeNativeMethods.IsWindow(new HandleRef(this, hwnd)))
            {
                throw new ArgumentException(
                    SR.HwndTarget_InvalidWindowHandle,
                    nameof(hwnd)
                    );
            }
            else if (processId != Environment.ProcessId)
            {
                throw new ArgumentException(
                    SR.HwndTarget_InvalidWindowProcess,
                    nameof(hwnd)
                    );
            }
            else if (threadId != SafeNativeMethods.GetCurrentThreadId())
            {
                throw new ArgumentException(
                    SR.HwndTarget_InvalidWindowThread,
                    nameof(hwnd)
                    );
            }

View on GitHub (pinned to 81131a70a4)