Skip to main content

How to Implement a Yes/No/Cancel Three-Option Prompt in Batch Script

Simple dual-choice prompts (Yes/No) are ubiquitous, but often you need a third option: Cancel. While "No" might mean "Don't do this, but keep going," "Cancel" usually means "Abort the entire script immediately." Providing this third choice prevents users from being "trapped" in a logic loop they didn't intend to enter.

In this guide, we will demonstrate how to use the choice command to implement a professional three-option prompt.

The choice command is the standard way to handle multi-option inputs in Windows. It is fast, handles errors automatically, and doesn't require the user to press Enter.

Implementation Script

@echo off
setlocal

echo.
echo Save configuration changes before exiting?
echo.

:: /c YNC (Options: [Y]es, [N]o, [C]ancel)
:: /m "Select an option: " (Custom prompt message)
:: /n (Do not display the choice keys in the prompt)
choice /c YNC /n /m "Select [Y]es, [N]o, or [C]ancel: "

:: Errorlevel values correspond to the order of choices in /c:
:: Errorlevel 1 = Y (first choice)
:: Errorlevel 2 = N (second choice)
:: Errorlevel 3 = C (third choice)
if %errorlevel% equ 3 goto :cancel_action
if %errorlevel% equ 2 goto :no_action
if %errorlevel% equ 1 goto :yes_action

:yes_action
echo.
echo [SAVING] Configuration saved.
goto :end

:no_action
echo.
echo [SKIP] Proceeding without saving.
goto :end

:cancel_action
echo.
echo [ABORT] Operation canceled by user.
pause
exit /b 1

:end
echo.
echo Script finished.

endlocal
pause

How choice errorlevels work:

  • The errorlevel is set to the 1-based index of the selected choice in the /c string.
  • For /c YNC, Y = 1, N = 2, C = 3.
  • The if errorlevel N syntax checks whether the errorlevel is greater than or equal to N. This means if errorlevel 1 matches all values 1, 2, and 3, which is not what you want. The correct approach is to check for equality (if %errorlevel% equ N) or to check from highest to lowest:
    if errorlevel 3 goto :cancel_action
    if errorlevel 2 goto :no_action
    if errorlevel 1 goto :yes_action

Adding a Timeout and Default Choice

For unattended scripts, you can add a timeout that defaults to "Cancel" after a set number of seconds:

choice /c YNC /t 10 /d C /n /m "Select [Y]es, [N]o, or [C]ancel (auto-cancel in 10s): "
  • /t 10: Wait 10 seconds for input.
  • /d C: Default to C (Cancel) if no key is pressed.

Method 2: The SET /P Method (Legacy/Custom)

If you need the user to type out full words or handle custom characters that choice doesn't support, you can use set /p. This method is more flexible but requires manual input validation.

Implementation Script

@echo off
setlocal enabledelayedexpansion

:prompt
set "userInp="
set /p "userInp=Install Update? (Yes / No / Cancel): "

:: Clear leading/trailing spaces
for /f "tokens=* delims= " %%a in ("!userInp!") do set "userInp=%%a"

:: Use IF /I for case-insensitive matching
if /i "!userInp!"=="Yes" goto :yes_action
if /i "!userInp!"=="No" goto :no_action
if /i "!userInp!"=="Cancel" goto :cancel_action

:: Handle invalid input
echo Invalid selection. Please type "Yes", "No", or "Cancel".
goto :prompt

:yes_action
echo.
echo [INSTALL] Starting update...
goto :end

:no_action
echo.
echo [SKIP] Update skipped.
goto :end

:cancel_action
echo.
echo [ABORT] Operation canceled by user.
pause
exit /b 1

:end
echo.
echo Script finished.

endlocal
pause

Improvements over the original:

  • Input trimming: Added for /f "tokens=* delims= " to remove leading and trailing spaces from the input, preventing issues like " Yes" or "Cancel " from failing the comparison.
  • Case-insensitive matching: Used if /i to handle variations like yes, YES, Yes, etc.
  • Input loop: Added a :prompt loop to re-ask the question if the input is invalid, rather than silently falling through to the end of the script.

Comparisons: Choice vs. Set /P

Featurechoiceset /p
User EffortSingle key (no Enter).Type word + Enter.
ValidationAutomatic (rejects other keys).Manual if checks required.
SpeedHighly efficient.Slower for the user.
ComplexitySimple indices (1, 2, 3).String comparisons.
Timeout SupportYes (/t flag).No.
Case SensitivityCase-insensitive by default.Requires /i flag in if statements.

Verdict: Use choice for almost all scenarios. It is more robust, prevents typos, and supports timeouts. Use set /p only when you need the user to type arbitrary text or when you must support Windows versions prior to Vista (which lack the choice command).

Best Practices

  1. Logical Order: Follow the industry standard "Yes, No, Cancel" order. Users are conditioned to look for these in this sequence.
  2. Explicit Labels: Always provide a goto for each choice. Do not rely on "falling into" the next section of code, as this leads to "spaghetti" logic that is hard to debug and maintain.
  3. Default with Timeout: For administrative scripts, consider adding a timeout to your choice command: choice /c YNC /t 10 /d C /m "...". This ensures that if no one is at the desk, the script defaults to "Cancel" for safety.
  4. Confirm the Abort: If the user selects "Cancel" on a major operation, show a final "Operation Aborted" message so they know exactly why the script stopped.
  5. Use /n to Hide Choice Keys: The /n flag prevents choice from displaying the available keys in the prompt (e.g., [Y,N,C]?). This allows you to write a cleaner, more custom prompt message.
  6. Exit with Error Code on Cancel: When the user cancels, use exit /b 1 (or another non-zero value) to signal failure to the calling process. This is important for scripts that are part of larger automation chains.

Conclusion

A three-option prompt provides a level of interactive granular control that simple Yes/No toggles lack. By using the choice command to facilitate Yes/No/Cancel inputs, you empower your users to manage their workflows with confidence, allowing them to save, skip, or safely abort processes as needed. This leads to a more professional and user-friendly automation tool.