stride3d/stride · error · InvalidOperationException

Unable to initialize the window manager.

Error message

Unable to initialize the window manager.

What it means

WindowManager installs a WinEvent hook via NativeHelper.SetWinEventHook to watch for window show/hide events. If the native call returns IntPtr.Zero the hook was not installed and the constructor throws InvalidOperationException, failing fast rather than running a manager that will never see window events.

Solutions

  1. Construct WindowManager on the UI/dispatcher thread that pumps messages
  2. Verify the process runs in an interactive desktop session (not a service/session 0)
  3. Catch the exception and degrade gracefully if window tracking is optional; check NativeHelper constants and the WinEvent parameters are correct

Example fix

// before
Task.Run(() => new WindowManager(dispatcher)); // no message pump
// after
dispatcher.Invoke(() => { manager = new WindowManager(dispatcher); });
Defensive patterns

Strategy: try-catch

Validate before calling

if (Environment.UserInteractive == false) skipWindowManagerInit();

Try / catch

try { manager = new WindowManager(dispatcher); } catch (InvalidOperationException ex) when (ex.Message.Contains("Unable to initialize")) { /* run without window tracking */ }

Prevention

When it happens

Trigger: SetWinEventHook failing at construction — typically because the calling thread is not running a message pump, an out-of-resources/desktop situation, or running in an environment where WinEvents are unavailable (e.g. certain services or non-interactive sessions).

Common situations: Constructing WindowManager on a background thread without a message loop; running inside a Windows Service or session 0 where UI hooks are restricted; restricted desktop or security software blocking hooks.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/157297b84287dc74. Report an issue: GitHub.

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Windows/WindowManager.cs:47

        private static IntPtr hook;
        private static Dispatcher dispatcher;
        private static bool initialized;

        /// <summary>
        /// Initializes a new instance of the <see cref="WindowManager"/> class.
        /// </summary>
        public WindowManager([NotNull] Dispatcher dispatcher)
        {
            if (dispatcher == null) throw new ArgumentNullException(nameof(dispatcher));
            if (initialized) throw new InvalidOperationException("An instance of WindowManager is already existing.");

            initialized = true;
            winEventProc = WinEventProc;
            WindowManager.dispatcher = dispatcher;
            uint processId = (uint)Process.GetCurrentProcess().Id;
            hook = NativeHelper.SetWinEventHook(NativeHelper.EVENT_OBJECT_SHOW, NativeHelper.EVENT_OBJECT_HIDE, IntPtr.Zero, winEventProc, processId, 0, NativeHelper.WINEVENT_OUTOFCONTEXT);
            if (hook == IntPtr.Zero)
                throw new InvalidOperationException("Unable to initialize the window manager.");

            Logger.Info($"{nameof(WindowManager)} initialized");
        }

#if DEBUG // Use a logger result for debugging
        public static Logger Logger { get; } = new LoggerResult();
#else
        public static Logger Logger { get; } = GlobalLogger.GetLogger(nameof(WindowManager));
#endif

        /// <summary>
        /// Gets the current main window.
        /// </summary>
        public static WindowInfo MainWindow { get; private set; }

        /// <summary>
        /// Gets the collection of currently visible modal windows.
        /// </summary>

View on GitHub (pinned to 96fad776d2)