dotnet/wpf · error · InvalidOperationException

InvalidOperationException

Error message

InvalidOperationException

What it means

WPF's stylus/touch (PenIMC) layer throws this bare InvalidOperationException from CheckedLockWispObjectFromGit when the native Win32 call LockWispObjectFromGit fails on Windows 8 or greater. Locking the WISP (Windows Ink Services Platform) Global Interface Table entry is a prerequisite for using the pen/ink subsystem; failure means the native tablet service did not grant the lock, so WPF aborts rather than continue with inconsistent state.

Solutions

  1. Ensure the Windows 'Tablet PC Input Service' (TabletInputService / TabSvc) is running on the machine.
  2. Check whether the app is running in an RDP/remote session; WISP real-time stylus is unavailable there - catch the exception or disable stylus-dependent features in remote sessions.
  3. Repair/verify Windows ink components (sfc /scannow, Windows Update, reinstall pen/display drivers).
  4. Wrap WPF window/ink initialization in try-catch and fall back to mouse-only input when WISP locking fails.

Example fix

// before (crash on RDP / no tablet service)
var win = new StylusWindow();

// after (degrade gracefully)
try
{
    var win = new StylusWindow();
}
catch (InvalidOperationException)
{
    // WISP GIT lock failed (no tablet service / RDP session)
    EnableMouseOnlyMode();
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before creating WPF windows in constrained environments
bool stylusLikelyAvailable =
    Environment.UserInteractive &&
    !IsRemoteSession() &&
    ServiceRunning("TabletInputService");

Try / catch

try
{
    InitializeWpfWindow();
}
catch (InvalidOperationException ex) when (IsWispLockFailure(ex))
{
    Log.Warn("WISP GIT lock failed; falling back to mouse-only input.");
    EnableMouseOnlyMode();
}

Prevention

When it happens

Trigger: A WPF app that uses stylus/touch input (Tablet service, InkCanvas, real-time stylus) calls LockWispManager, which invokes CheckedLockWispObjectFromGit; the P/Invoke LockWispObjectFromGit returns false (native failure) on Windows 8+, causing the throw. Happens during TabletService/WispTabletDevice initialization.

Common situations: RDP/terminal-server or VM sessions where the tablet service is unavailable or disabled; Windows Tablet Input Service (TabletInputService/TabSvc) stopped or broken; systems where WISP components are corrupted or the pen driver stack fails; headless machines or sessions without a visible desktop that still touch the stylus code path.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/Win32/UnsafeNativeMethodsPenimc.cs:181

            return ((IPimcManager3)pimcManagerObj);
        }

        #region COM Locking/Unlocking Functions

        #region General

        /// <summary>
        /// Calls WISP GIT lock functions on Win8+.
        /// On Win7 these will always fail since WISP objects are always proxies (WISP is out of proc).
        /// </summary>
        /// <param name="gitKey">The GIT key for the object to lock.</param>
        internal static void CheckedLockWispObjectFromGit(UInt32 gitKey)
        {
            if (OSVersionHelper.IsOsWindows8OrGreater)
            {
                if (!LockWispObjectFromGit(gitKey))
                {
                    throw new InvalidOperationException();
                }
            }
        }

        /// <summary>
        /// Calls WISP GIT unlock functions on Win8+.
        /// On Win7 these will always fail since WISP objects are always proxies (WISP is out of proc).
        /// </summary>
        /// <param name="gitKey">The GIT key for the object to unlock.</param>
        internal static void CheckedUnlockWispObjectFromGit(UInt32 gitKey)
        {
            if (OSVersionHelper.IsOsWindows8OrGreater)
            {
                if (!UnlockWispObjectFromGit(gitKey))
                {
                    throw new InvalidOperationException();
                }
            }

View on GitHub (pinned to 81131a70a4)