dotnet/wpf · error · Win32Exception

Win32Exception

Error message

Win32Exception

What it means

Win32Exception is thrown when a Win32 API call fails and the library surfaces the OS error code. Here IsWOW64Process opens a process handle from an HWND via SafeProcessHandle; if the handle is invalid (the window's owning process cannot be opened, e.g. access denied or the process exited), a parameterless Win32Exception is raised. This happens during remote-bitness detection when reading text within a UIAutomation structure.

Solutions

  1. Re-check that the target window/process is still alive (IsWindow / HasExited) before querying and skip bitness detection if it died
  2. Retry the operation after the window is re-resolved; transient invalid handles often mean the window was destroyed
  3. Run the automation client with sufficient privileges (or the target unelevated) so the process handle can be opened
  4. Catch Win32Exception around GetTextWithinStructure and fall back to non-bitness-aware text retrieval

Example fix

// before
var text = GetTextWithinStructure(hwnd);
// after
string text = null;
if (SafeNativeMethods.IsWindow(hwnd))
{
    try { text = GetTextWithinStructure(hwnd); }
    catch (Win32Exception) { /* target process unavailable; degrade gracefully */ }
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!SafeNativeMethods.IsWindow(hwnd)) return; // window gone; skip bitness detection

Type guard

static bool CanQueryProcess(IntPtr hwnd) => SafeNativeMethods.IsWindow(hwnd);

Try / catch

try { var text = GetTextWithinStructure(hwnd); }
catch (Win32Exception ex) { Log.Warn($"bitness/text query failed: {ex.NativeErrorCode}"); /* fallback */ }

Prevention

When it happens

Trigger: GetTextWithinStructure -> GetTextWithinStructureRemoteBitness -> IsWOW64Process is called with an HWND whose owning process handle cannot be created: the target process has already exited, is protected (elevated/protected-mode process), or the caller lacks PROCESS_QUERY_INFORMATION rights.

Common situations: Automating a window whose process crashes/closes mid-automation; inspecting elevated apps (Task Manager, UAC dialogs) from a non-elevated client; cross-session automation (services, different user sessions); Internet Explorer protected mode on legacy Windows.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/CommonXSendMessage.cs:1482

                                    return copyTo.GetStringAuto();
                                }
                            }
                        }
                    }
                }
            }

            return "";
        }

        // This method will determine if the process is running in 32-bit emulation mode on a 64-bit machine.
        private static bool IsWOW64Process(IntPtr hwnd)
        {
            using (SafeProcessHandle hProcess = new SafeProcessHandle(hwnd))
            {
                if (hProcess.IsInvalid)
                {
                    throw new Win32Exception();
                }

                // Windows XP(major version 5 and minor version 1) and above
                if (Environment.OSVersion.Version.Major > 5 || (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1))
                {
                    try
                    {
                        // IsWow64Process() implemented in Windows XP
                        bool isWOW64Process;

                        if (!Misc.IsWow64Process(hProcess, out isWOW64Process))
                        {
                            // Function failed. Assume not running under WOW64.
                            return false;
                        }

                        return isWOW64Process;
                    }

View on GitHub (pinned to 81131a70a4)