stride3d/stride · error · InvalidOperationException

An instance of WindowManager is already existing.

Error message

An instance of WindowManager is already existing.

What it means

WindowManager is a process-wide singleton: a static initialized flag prevents a second instantiation because it installs a native WinEvent hook that cannot coexist with another manager. The constructor throws InvalidOperationException if an instance was already created.

Solutions

  1. Create WindowManager once and reuse the existing instance (expose it via a static/singleton accessor)
  2. Guard construction: keep a reference and skip re-instantiation if it already exists
  3. Dispose the previous instance and restart the process or refactor to allow re-init if a fresh manager is truly needed

Example fix

// before
var manager = new WindowManager(dispatcher); // second call in process
// after
private static WindowManager manager;
if (manager == null) manager = new WindowManager(dispatcher);
Defensive patterns

Strategy: try-catch

Validate before calling

if (WindowManager.Instance != null) useExisting(); else create();

Try / catch

try { manager = new WindowManager(dispatcher); } catch (InvalidOperationException ex) when (ex.Message.Contains("already existing")) { manager = WindowManager.Existing; }

Prevention

When it happens

Trigger: Calling new WindowManager(dispatcher) twice in the same process, e.g. once at startup and again after re-initializing services or re-creating a ViewModel that owns one.

Common situations: Double application initialization (e.g. both App startup and a service locator warm-up); plugin or test harness constructing its own instance; forgetting Dispose does not reset initialized.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

    public class WindowManager : IDisposable
    {
        private static readonly List<WindowInfo> ModalWindowsList = new List<WindowInfo>();
        private static readonly List<WindowInfo> BlockingWindowsList = new List<WindowInfo>();
        private static readonly HashSet<WindowInfo> AllWindowsList = new HashSet<WindowInfo>();

        // This must remains a field to prevent garbage collection!
        private static NativeHelper.WinEventDelegate winEventProc;
        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

View on GitHub (pinned to 96fad776d2)