dotnet/wpf · error · InvalidOperationException
SR.OperationCannotBePerformed
Error message
SR.OperationCannotBePerformed
What it means
When SetVisualState(WindowVisualState.Normal) is requested, the provider refuses if the window's style has WS_DISABLED set: a disabled window cannot respond to state changes, so InvalidOperationException(SR.OperationCannotBePerformed) is thrown from HwndProxyElementProvider.SetVisualState (HwndProxyElementProvider.cs:299).
Solutions
- Re-enable the window first (EnableWindow(hwnd, true) from the owning process, or via the app's own UI) before requesting WindowVisualState.Normal.
- Skip the restore operation when IsWindowEnabled indicates the window is disabled and wait for the app to re-enable it.
- If you control the target app, stop disabling the main window while automation is active, or handle WM_SC commands regardless.
- Catch InvalidOperationException from WindowPattern.SetVisualState and fall back to SetWindowPlacement only if you own the process.
Example fix
// before
windowPattern.SetVisualState(WindowVisualState.Normal); // throws if window is WS_DISABLED
// after
if ((GetWindowLong(hwnd, GWL_STYLE) & WS_DISABLED) == 0)
{
windowPattern.SetVisualState(WindowVisualState.Normal);
}
else
{
// window is disabled; enable it in the target app first or wait
} Defensive patterns
Strategy: validation
Validate before calling
bool canRestore = !IsBitSet(GetWindowLong(hwnd, GWL_STYLE), WS_DISABLED); if (!canRestore) throw new SkipException("window disabled"); Try / catch
try { windowPattern.SetVisualState(WindowVisualState.Normal); } catch (InvalidOperationException) { /* window is WS_DISABLED; wait or skip */ } Prevention
- Check WindowPattern properties (CanMinimize/CanMaximize) and window style before state changes
- Avoid disabling main windows with EnableWindow(false) while automation is active
- Wait for busy/disabled states to clear before issuing window commands
- Treat InvalidOperationException from SetVisualState as 'operation not applicable', not a test failure
When it happens
Trigger: Calling IWindowProvider.SetVisualState(WindowVisualState.Normal) on a window whose GWL_STYLE contains WS_DISABLED (window created disabled or disabled via EnableWindow(hwnd,false)).
Common situations: Automating modal dialogs or windows whose owner disabled them to block input; apps that call EnableWindow(false) during busy operations; test frameworks trying to restore a disabled splash/progress window.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- ElementNotEnabledException
- new Win32Exception()
- SR.UnexpectedWindowState (state)
- throw new…
- Win32Exception(errorCode)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/63939d13a0280abe.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/MS/Internal/Automation/HwndProxyElementProvider.cs:299
//
// Interface IWindowProvider
//
//------------------------------------------------------
#region Interface IWindowProvider
void IWindowProvider.SetVisualState( WindowVisualState state )
{
if ( !SafeNativeMethods.IsWindow( _hwnd ) )
throw new ElementNotAvailableException();
switch ( state )
{
case WindowVisualState.Normal:
{
// you can't really do anything to a disabled window
if ( IsBitSet(GetWindowStyle(), SafeNativeMethods.WS_DISABLED) )
throw new InvalidOperationException(SR.OperationCannotBePerformed);
// If already in the normal state, do not need to do anything.
if (((IWindowProvider)this).VisualState == WindowVisualState.Normal)
{
return;
}
ClearMenuMode();
UnsafeNativeMethods.WINDOWPLACEMENT wp = new UnsafeNativeMethods.WINDOWPLACEMENT
{
length = Marshal.SizeOf(typeof(UnsafeNativeMethods.WINDOWPLACEMENT))
};
// get the WINDOWPLACEMENT information
if (!Misc.GetWindowPlacement(_hwnd, ref wp))
{
throw new InvalidOperationException(SR.OperationCannotBePerformed);
}View on GitHub (pinned to 81131a70a4)