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
- Construct WindowManager on the UI/dispatcher thread that pumps messages
- Verify the process runs in an interactive desktop session (not a service/session 0)
- 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
- Construct on a message-pumping (UI) thread
- Don't use in services/non-interactive sessions
- Make window tracking optional with graceful degradation
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
- An error occurred while disposing the window manager.
- The hwnd cannot be null
- A dependency object is already attached to this instance of…
- A dependency object must be attached in order to register a…
- A dependency object must be attached in order to unregister…
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)