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
- Re-check that the target window/process is still alive (IsWindow / HasExited) before querying and skip bitness detection if it died
- Retry the operation after the window is re-resolved; transient invalid handles often mean the window was destroyed
- Run the automation client with sufficient privileges (or the target unelevated) so the process handle can be opened
- 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
- Verify IsWindow before automating an HWND
- Avoid automating elevated or protected processes from a lower-integrity client
- Handle windows closing mid-automation gracefully
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
- ElementNotAvailableException
- ElementNotAvailableException
- ElementNotEnabledException
- InvalidOperationException(SR.OperationCannotBePerformed, e)
- Win32Exception(Marshal.GetLastWin32Error())
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)