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

  1. Re-enable the window first (EnableWindow(hwnd, true) from the owning process, or via the app's own UI) before requesting WindowVisualState.Normal.
  2. Skip the restore operation when IsWindowEnabled indicates the window is disabled and wait for the app to re-enable it.
  3. If you control the target app, stop disabling the main window while automation is active, or handle WM_SC commands regardless.
  4. 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

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


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)