BCUninstaller/Bulk-Crap-Uninstaller · info · OperationCanceledException

User cancelled the operation

Error message

User cancelled the operation

What it means

OperationCanceledException thrown inside AutomatizeStatusCallback whenever the _abort flag is set, before relaying any further status update. This is the cooperative cancellation channel: the host sets UninstallHandler._abort=true and the next status callback from the automation engine throws, unwinding the operation. Program.Main maps OperationCanceledException to ResultWin32.ERROR_CANCELLED.

Source

Thrown at source/UninstallerAutomatizer/Automation/UninstallHandler.cs:246

                if (ex.UninstallerProcess != null && KillOnFail)
                {
                    try
                    {
                        ex.UninstallerProcess.Kill(true);
                    }
                    catch
                    {
                        // Ignore process errors, can't do anything about it
                    }
                }

                Program.ReturnValue = ResultWin32.ERROR_FUNCTION_FAILED;
            }
        }

        private void AutomatizeStatusCallback(string s)
        {
            if (_abort) throw new OperationCanceledException(Localization.Message_UserCancelled);
            OnStatusUpdate(new UninstallHandlerUpdateArgs(UninstallHandlerUpdateKind.Normal, s));
        }

        private UninstallHandlerUpdateArgs _previousArgs;

        protected virtual void OnStatusUpdate(UninstallHandlerUpdateArgs e)
        {
            // Filter out repeated updates
            if (Equals(_previousArgs, e)) return;
            _previousArgs = e;

            StatusUpdate?.Invoke(this, e);
            Console.WriteLine(e.Message);
        }

        public void Abort()
        {
            _abort = true;

View on GitHub (pinned to 608321de98)

Solutions

  1. If cancellation is unexpected, find where _abort is being set (UI cancel handler, watchdog) and add logging there.
  2. Handle it at the top level exactly as Program.Main does: catch OperationCanceledException and return ERROR_CANCELLED rather than treating it as an error.
  3. If you need cleanup on cancel, run it in a finally / using around the UninstallNsisQuietly call.
  4. Do not swallow it silently; ERROR_CANCELLED is the contractually correct exit code for the caller.

Example fix

// before - abort looks like a crash to the caller
catch (Exception e) { return Error(e); }

// after - treat cancellation as a normal non-error exit
try { RunUninstall(); }
catch (OperationCanceledException) { return (int)ResultWin32.ERROR_CANCELLED; }
catch (Exception e) { return Error(e); }
Defensive patterns

Strategy: try-catch

Try / catch

try { /* run uninstall */ }
catch (OperationCanceledException) { return (int)ResultWin32.ERROR_CANCELLED; }

Prevention

When it happens

Trigger: User or controller sets the abort flag (e.g. clicks cancel) while AutomatedUninstallManager is relaying status messages through the callback. Any subsequent call to AutomatizeStatusCallback then throws. The exception propagates up through the automation methods to Program.Main's catch(OperationCanceledException).

Common situations: A GUI batch-uninstall app lets the user cancel mid-way; flipping the cancel button sets _abort and the next status tick aborts. A watchdog timer aborts a stalled uninstall. Tests that set _abort to short-circuit a run.

Related errors


AI-assisted analysis of BCUninstaller/Bulk-Crap-Uninstaller@608321de98 (2026-08-13). Data as JSON: /api/errors/cc7d38f247748a22. Report an issue: GitHub.