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
- If cancellation is unexpected, find where _abort is being set (UI cancel handler, watchdog) and add logging there.
- Handle it at the top level exactly as Program.Main does: catch OperationCanceledException and return ERROR_CANCELLED rather than treating it as an error.
- If you need cleanup on cancel, run it in a finally / using around the UninstallNsisQuietly call.
- 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
- Catch OperationCanceledException distinctly from other exceptions and return ERROR_CANCELLED.
- Do cleanup in finally blocks so an abort leaves no orphaned processes.
- Log where _abort is set to distinguish intended cancellation from accidental aborts.
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
- This application does not have a valid uninstaller
- Uninstaller timed out
- The system cannot find the file specified. Indicates that th
- The system cannot find the path specified. Indicates that th
- Access is denied. Indicates that user has no access right to
AI-assisted analysis of BCUninstaller/Bulk-Crap-Uninstaller@608321de98 (2026-08-13).
Data as JSON: /api/errors/cc7d38f247748a22.
Report an issue: GitHub.