{"record":{"id":"e9cdde52537754b5","repo":"BCUninstaller/Bulk-Crap-Uninstaller","slug":"automatic-uninstallation-failed","errorCode":null,"errorMessage":"Automatic uninstallation failed.","messagePattern":"Automatic uninstallation failed\\.","errorType":"exception","errorClass":"AutomatedUninstallException","httpStatus":null,"severity":"error","filePath":"source/UninstallerAutomatizer/Automation/AutomatedUninstallManager.cs","lineNumber":135,"sourceCode":"\n                if (prs != 0)\n                {\n                    app = Application.Attach(prs);\n                }\n                else\n                {\n                    // Get all processes with name in format [A-Z]u_ (standard NSIS naming scheme, e.g. \"Au_.exe\") \n                    // and select the last one to launch. (Most likely to be ours)\n                    var uninstallProcess = Process.GetProcesses()\n                        .Where(x => x.ProcessName.Length == 3 && x.ProcessName.EndsWith(\"u_\", StringComparison.Ordinal))\n                        .OrderByDescending(x => x.StartTime).First();\n                    app = Application.Attach(uninstallProcess);\n                }\n            }\n            catch (Exception e)\n            {\n                var process = app != null ? ProcessTools.GetProcessByIdSafe(app.ProcessId) : null;\n                throw new AutomatedUninstallException(Localization.Message_Automation_Failed, e, uninstallerCommand, process ?? pr);\n            }\n\n            if (app != null)\n                AutomatizeApplication(app, statusCallback);\n        }\n\n        public static void AutomatizeApplication(Application app, Action<string> statusCallback)\n        {\n            if (app == null) throw new ArgumentNullException(nameof(app));\n            if (statusCallback == null) throw new ArgumentNullException(nameof(statusCallback));\n\n            var windows = new List<Window>();\n\n            void VisibleChangedHandler(object sender, EventArgs args) => SetWindowVisibility(windows, HideAutomatizedWindows);\n            HideAutomatizedWindowsChanged += VisibleChangedHandler;\n\n            try\n            {","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/BCUninstaller/Bulk-Crap-Uninstaller/blob/608321de98e92297377b1eb69029af55c25504a1/source/UninstallerAutomatizer/Automation/AutomatedUninstallManager.cs#L117-L153","documentation":"This is the catch-all wrapper thrown by the catch(Exception) block in UninstallNsisQuietly. It wraps any exception that occurs during process start, the NSIS self-extraction wait (pr.WaitForExit), child-process lookup via ProcessTools.GetChildProcesses, or the fallback name-based process scan and Application.Attach. It is an AutomatedUninstallException carrying the original command, the inner exception, and whichever process (app or pr) was obtained, so callers get a single typed error with full context.","triggerScenarios":"pr.WaitForExit() never returns or the extractor crashes; ProcessTools.GetChildProcesses(pr.Id).FirstOrDefault() returns 0 AND the fallback Process.GetProcesses().Where(...EndsWith(\"u_\")).OrderByDescending(StartTime).First() throws InvalidOperationException because no matching NSIS process exists (sequence contains no elements). Application.Attach fails because the extracted process already exited or access is denied. Any underlying FlaUI/White exception during attach.","commonSituations":"The NSIS uninstaller extracted then closed too fast for GetChildProcesses/GetProcesses to catch it. Another application happens to match the [A-Z]u_ naming scheme and is picked up, then fails to attach. The uninstaller prompted for elevation and the elevated copy is a different process tree invisible to the current token. Timing races on slow VMs where extraction is slow but child enumeration returns empty.","solutions":["Inspect the InnerException of the caught AutomatedUninstallException to find the real cause (InvalidOperationException 'Sequence contains no elements', access denied, etc.).","Ensure the uninstaller is launched with the same elevation level it expects so the extracted child process is in a visible process tree.","If GetChildProcesses returns 0 and no 'Xu_' process exists, the uninstaller may have completed or failed extraction; check its exit code before relying on attach.","Run on a session with an interactive desktop; NSIS extraction launches a GUI child that cannot be enumerated from a non-interactive service account."],"exampleFix":"// before - catch is generic and hides root cause from the caller\ntry { UninstallNsisQuietly(cmd, cb); }\ncatch (Exception e) { log(e.Message); }\n\n// after - catch the typed wrapper and surface the inner exception\ntry { UninstallNsisQuietly(cmd, cb); }\ncatch (AutomatedUninstallException e)\n{\n    log($\"{e.Message} (cmd={e.Command})\");\n    if (e.InnerException != null) log(e.InnerException);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { AutomatedUninstallManager.UninstallNsisQuietly(cmd, cb); }\ncatch (AutomatedUninstallException ex)\n{\n    // ex.InnerException is the real cause; ex.Command and ex.Process give context.\n    Log(ex.InnerException ?? ex);\n}","preventionTips":["Always read InnerException on AutomatedUninstallException to find the root failure.","Launch the uninstaller with matching elevation so the extracted child process is in an attachable process tree.","Confirm the uninstaller actually self-extracts before relying on child-process enumeration."],"tags":["nsis","automation","process-attach","wrapper-exception","uninstaller"],"backgroundTag":null,"analyzedSha":"608321de98e92297377b1eb69029af55c25504a1","analyzedAt":"2026-08-13T12:17:35.389Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}