dotnet/wpf · error · Win32Exception
Win32Exception(Marshal.GetLastWin32Error())
Error message
Win32Exception(Marshal.GetLastWin32Error())
What it means
After sending WM_UPDATEUISTATE (to hide accelerators/focus cues) via SendMessage, the code treats a non-zero return as failure and throws a Win32Exception built from Marshal.GetLastWin32Error(). This surfaces OS-level failures while WindowsFormsHost configures the WinForms child control's UI state.
Solutions
- Check that the WindowsFormsHost and its Child handles are alive (IsHandleCreated) before focus/keyboard operations.
- Wrap interop keyboard calls in try-catch for Win32Exception and ignore during teardown.
- Verify the child control is not disposed while the host updates UI state.
- If reproducible, ensure the control's Handle is created (force Handle access) before hosting operations.
Example fix
// before
host.Focus(); // may hit disposed handle -> Win32Exception
// after
if (host.Child != null && host.Child.IsHandleCreated)
{
try { host.Focus(); }
catch (System.ComponentModel.Win32Exception) { /* handle gone during teardown */ }
} Defensive patterns
Strategy: try-catch
Validate before calling
if (host.Child == null || !host.Child.IsHandleCreated || host.Child.IsDisposed)
return; // skip UI-state update Type guard
bool HasLiveHandle(System.Windows.Forms.Control c) => c != null && c.IsHandleCreated && !c.IsDisposed;
Try / catch
try { SendUiStateUpdate(); }
catch (Win32Exception ex) { log.Warn("WM_UPDATEUISTATE failed (handle may be gone)", ex); } Prevention
- Check IsHandleCreated and IsDisposed before interop calls
- Unhook focus/keyboard interop handlers on host unload to avoid calls after teardown
- Treat Win32Exception during window close as benign and swallow/log it
When it happens
Trigger: The control's handle is invalid/destroyed when the message is sent (host disposed during teardown or before handle creation), or the target window fails to process WM_UPDATEUISTATE, returning non-zero.
Common situations: Closing or hiding a WPF window containing a WindowsFormsHost during keyboard focus transitions; handle recreation on theme/display changes; races during window close.
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
- throw new Win32Exception();
- Win32Exception
- new System.ComponentModel.Win32Exception(win32Error)
- SR.ChildWindowNotCreated
- SR.InvalidEventHandle
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/c05a650c6c613404.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsFormsIntegration/System/Windows/Integration/WindowsFormsHost.cs:967
// (sometimes cues were shown, sometimes not. This forces it to a known state.
UpdateUIState(NativeMethods.UIS_SET);
}
/// <summary>
/// For keyboard interop
/// Ensure the visual shortcut key cues on controls are in the same visual
/// state that we expect. This is a workaround for odd Windows API.
/// </summary>
internal void UpdateUIState(int uiAction)
{
Debug.Assert(uiAction == NativeMethods.UIS_INITIALIZE || uiAction == NativeMethods.UIS_SET, "Unexpected uiAction");
int toSet = NativeMethods.UISF_HIDEACCEL | NativeMethods.UISF_HIDEFOCUS;
if (UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle),
NativeMethods.WM_UPDATEUISTATE,
(IntPtr)(uiAction | (toSet << 16)),
IntPtr.Zero) != IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
// CSS Added for keyboard interop
// Catch WM_CHAR messages which weren't handled by Avalon
// (including mnemonics which were typed without the "Alt" key)
private void InputManager_PostProcessInput(object sender, SWI.ProcessInputEventArgs e)
{
// Should return immediately if this WFH is not in the active Window
PresentationSource presentationSource = PresentationSource.FromVisual(this._host);
if (presentationSource == null)
{
return;
}
Window presentationSourceWindow = presentationSource.RootVisual as Window;
//CSS This active window check may not work for multiple levels of nesting...
// RootVisual isn't top level window. Should we traverse upward through nested levels?View on GitHub (pinned to 81131a70a4)