{"record":{"id":"99381c35611cdee9","repo":"BCUninstaller/Bulk-Crap-Uninstaller","slug":"reoccuring-popup-window-detected","errorCode":null,"errorMessage":"Reoccuring popup window detected!","messagePattern":"Reoccuring popup window detected!","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"warning","filePath":"source/UninstallerAutomatizer/Automation/AutomatedUninstallManager.cs","lineNumber":277,"sourceCode":"            Thread.Sleep(100);\n        }\n\n        private static void ProcessNsisPopups(Application app, Window mainWindow, ICollection<string> seenWindows, Action<string> statusCallback)\n        {\n            // Check for popups, they are opened as an extra window.\n            var currentWindows = app.GetAllTopLevelWindows(WhiteAdapter.Automation);\n            var popupWindow = currentWindows.SingleOrDefault(x => !x.Equals(mainWindow));\n\n            if (popupWindow == null)\n            {\n                popupWindow = mainWindow.ModalWindows.FirstOrDefault();\n                if (popupWindow == null)\n                    return;\n            }\n\n            var footprint = string.Join(\";\", popupWindow.FindAllChildren().Select(x => x.Name)) + popupWindow.Title + popupWindow.ActualWidth + popupWindow.ActualHeight;\n            if (seenWindows.Contains(footprint))\n                throw new InvalidOperationException(Localization.Message_Automation_PopupRecurringFound);\n            seenWindows.Add(footprint);\n            statusCallback(string.Format(Localization.Message_Automation_PopupFound, popupWindow.Title));\n\n            while (!popupWindow.IsAvailable)\n            {\n                TryClickNextNsisButton(popupWindow, statusCallback);\n\n                app.WaitWhileBusy();\n                popupWindow.WaitUntilClickable();\n                Thread.Sleep(100);\n            }\n            statusCallback(Localization.Message_Automation_PopupClosed);\n        }\n\n        private static void TryClickNextNsisButton(Window target, Action<string> statusCallback)\n        {\n            statusCallback(\"Looking for buttons to press...\");\n","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/BCUninstaller/Bulk-Crap-Uninstaller/blob/608321de98e92297377b1eb69029af55c25504a1/source/UninstallerAutomatizer/Automation/AutomatedUninstallManager.cs#L259-L295","documentation":"InvalidOperationException thrown by ProcessNsisPopups when a popup window's computed footprint (children names + title + width + height) matches one already recorded in seenWindows. The library tracks popup footprints to detect that the automation is stuck re-opening the same dialog without making progress; rather than loop forever it bails out with this error. The footprint is built from popupWindow.FindAllChildren().Select(x=>x.Name) joined with the title and dimensions.","triggerScenarios":"TryClickNextNsisButton clicks a control but the same popup reappears with identical contents on the next ProcessNsisPopups pass, so its footprint is already in seenWindows. This happens when the clicked button does not actually dismiss the popup (wrong button chosen, or a confirmation dialog re-prompts). A popup that re-shows after being dismissed because the underlying action failed.","commonSituations":"NSIS dialog asks 'are you sure?' and automation picks a button that loops it back. A license/custom page with no recognizable forward button keeps reappearing. A localized button name is missing from the Good list so the heuristic re-clicks a non-advancing control. The popup has dynamic content that happens to keep the same footprint each cycle.","solutions":["Examine the recurring popup's title/children (the footprint inputs) to identify which dialog cannot be advanced.","Add the correct forward/confirm button's automation ID or localized name to GoodButtonIds/GoodButtonNames so TryClickNextNsisButton advances it.","Add cancel/dangerous buttons to CancelButtonIds/BadButtonIds to prevent re-clicking them.","If the popup genuinely needs a non-button action (e.g. radio selection first), extend the automation to handle that specific control before clicking Next."],"exampleFix":"// before - heuristic keeps clicking a control that does not advance the popup\n// after - register the popup's actual forward control in the good-button lists\nprivate static readonly string[] GoodButtonIds =\n    { NsisForwardAutomationId, NsisYesAutomationId, \"1234\" /* custom forward */ };","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { AutomatedUninstallManager.AutomatizeApplication(app, cb); }\ncatch (InvalidOperationException ex) when (ex.Message == Localization.Message_Automation_PopupRecurringFound)\n{\n    // automation is stuck on one popup; surface to user for manual handling or extend button lists\n}","preventionTips":["Register every forward/confirm control (localized names and automation IDs) in GoodButtonNames/GoodButtonIds.","Register cancel/dangerous controls in Cancel/Bad lists to avoid re-clicking them.","Treat a recurring-popup error as a signal the uninstaller needs a custom automation path."],"tags":["nsis","ui-automation","popup","infinite-loop-guard","uninstaller"],"backgroundTag":null,"analyzedSha":"608321de98e92297377b1eb69029af55c25504a1","analyzedAt":"2026-08-13T12:17:35.389Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}