{"record":{"id":"f3e4ee589f45a7b2","repo":"stride3d/stride","slug":"an-instance-of-windowmanager-is-already-existing","errorCode":null,"errorMessage":"An instance of WindowManager is already existing.","messagePattern":"An instance of WindowManager is already existing\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation.Wpf/Windows/WindowManager.cs","lineNumber":39,"sourceCode":"    public class WindowManager : IDisposable\n    {\n        private static readonly List<WindowInfo> ModalWindowsList = new List<WindowInfo>();\n        private static readonly List<WindowInfo> BlockingWindowsList = new List<WindowInfo>();\n        private static readonly HashSet<WindowInfo> AllWindowsList = new HashSet<WindowInfo>();\n\n        // This must remains a field to prevent garbage collection!\n        private static NativeHelper.WinEventDelegate winEventProc;\n        private static IntPtr hook;\n        private static Dispatcher dispatcher;\n        private static bool initialized;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"WindowManager\"/> class.\n        /// </summary>\n        public WindowManager([NotNull] Dispatcher dispatcher)\n        {\n            if (dispatcher == null) throw new ArgumentNullException(nameof(dispatcher));\n            if (initialized) throw new InvalidOperationException(\"An instance of WindowManager is already existing.\");\n\n            initialized = true;\n            winEventProc = WinEventProc;\n            WindowManager.dispatcher = dispatcher;\n            uint processId = (uint)Process.GetCurrentProcess().Id;\n            hook = NativeHelper.SetWinEventHook(NativeHelper.EVENT_OBJECT_SHOW, NativeHelper.EVENT_OBJECT_HIDE, IntPtr.Zero, winEventProc, processId, 0, NativeHelper.WINEVENT_OUTOFCONTEXT);\n            if (hook == IntPtr.Zero)\n                throw new InvalidOperationException(\"Unable to initialize the window manager.\");\n\n            Logger.Info($\"{nameof(WindowManager)} initialized\");\n        }\n\n#if DEBUG // Use a logger result for debugging\n        public static Logger Logger { get; } = new LoggerResult();\n#else\n        public static Logger Logger { get; } = GlobalLogger.GetLogger(nameof(WindowManager));\n#endif\n","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation.Wpf/Windows/WindowManager.cs#L21-L57","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Create WindowManager once and reuse the existing instance (expose it via a static/singleton accessor)","Guard construction: keep a reference and skip re-instantiation if it already exists","Dispose the previous instance and restart the process or refactor to allow re-init if a fresh manager is truly needed"],"exampleFix":"// before\nvar manager = new WindowManager(dispatcher); // second call in process\n// after\nprivate static WindowManager manager;\nif (manager == null) manager = new WindowManager(dispatcher);","handlingStrategy":"try-catch","validationCode":"if (WindowManager.Instance != null) useExisting(); else create();","typeGuard":null,"tryCatchPattern":"try { manager = new WindowManager(dispatcher); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"already existing\")) { manager = WindowManager.Existing; }","preventionTips":["Use a singleton accessor","Initialize once at app startup","Never re-create during service restarts"],"tags":["wpf","singleton","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}