How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?

1. Documentations for the Windows commands

I suggest bookmarking in your browser:

There can be get help for each Windows command by running in a command prompt window the command with /? as parameter, for example if /?, set /?, … The execution of help results in an output of an incomplete list of Windows commands with a brief description.


2. Usage of SET /P for user prompts

It is advisable not using set /p if the user should choose from one of several offered options. There are multiple facts which must be taken into account on prompting a user for entering a string and assigning it to an environment variable:

  1. The environment variable MyVar is not modified on usage of set /P "MyVar=Your choice: " if the user presses intentionally or by mistake just RETURN or ENTER. This means if the environment variable MyVar is not defined already before the user prompt, it is still not defined after the user prompt finished with just hitting key RETURN. And if MyVar is defined already before the user prompt, it keeps its value unmodified in case of the user presses just RETURN or ENTER. The command SET exits with error value 1 on user did not enter a string at all as documented by What are the ERRORLEVEL values set by internal cmd.exe commands?

  2. The user has the freedom to type any string on being prompted with set /P. The batch file author has no control on what the user really enters. So the batch file author must take into account that the user enters by mistake or intentionally a string which could result in an exit of batch file execution because of a syntax error, or it does something completely different as it is defined for.

A simple example:

@echo on
:MainMenu
@set /P "menu=Your choice: "
if %menu% == 1 goto Label1
if %menu% == 2 goto Label2
goto MainMenu

:Label1
@echo Option 1 was chosen, fine.
exit /B

:Label2
@echo Option 2 was chosen, okay.

This batch file with echo on instead of echo off at top is started from within a command prompt window for debugging purposes.

Just RETURN is pressed on user prompt on first run. Windows command interpreter exits the batch file processing because first IF condition is preprocessed before execution of IF command to:

if  == 1 goto Label1

There is obviously missing the first argument. cmd.exe encounters this syntax error and exits batch processing with an appropriate error message. The reason is the missing definition of environment variable menu which is not defined before user prompt and is still not defined after user prompt.

The string 2 is entered on second run of the batch file from within command prompt window and the batch file works as expected.

On third run of the batch file from within same command prompt window again just RETURN is pressed on user prompt. The batch file outputs again the second message. Why? The environment variable menu is still defined from second batch file execution with that string and the variable was not modified on pressing RETURN.

Okay, let us modify the example batch file to:

@echo on
:MainMenu
@set "menu=2"
@set /P "menu=Your choice: "
if "%menu%" == "1" goto Label1
if "%menu%" == "2" goto Label2
goto MainMenu

:Label1
@echo Option 1 was chosen, fine.
exit /B

:Label2
@echo Option 2 was chosen, okay.

This is already better as now environment variable menu is always predefined with value 2. So if the user enters nothing, a jump to Label2 is done. Also the value of previous run of variable menu has no effect anymore on execution of the batch file.

Another solution would be making use of exit code 1 on user not entering a string at all and define only in this case the environment variable with a default value by using:

@set /P "menu=Your choice: " || set "menu=2"

Single line with multiple commands using Windows batch file describes the conditional execution operator || to run the second command set "menu=2" only if the first executed prompt command set /P "menu=Your choice: " exits with an exit code not equal 0 as done when the user does not enter anything at all.

Thanks aschipfl for this contribution.

But is that really secure and fail safe now?

No, it isn’t. The user still can enter by mistake a wrong string.

For example the user enters by mistake " instead of 2 which is easy on German keyboards as CapsLock+2 or Shift+2 results in entering ". The first IF command line after preprocessing is now:

if """ == "1" goto Label1

And this is again an invalid command line resulting in an exit of batch file processing because of a syntax error.

Let us assume a user enters on prompt the string:

" == "" call dir "%USERPROFILE%\Desktop" & rem 

Note: There is a space at end.

The first IF condition is preprocessed by Windows command interpreter to:

if "" == "" call dir "%USERPROFILE%\Desktop"   & rem " == "1" goto Label1

It can be seen that the batch file executes now a command not written in the batch file at all on both IF conditions.

How to get a user prompt fail safe and secure?

A user prompt can be made fail safe and secure by using delayed variable expansion at least for the code evaluating the string input by the user.

@echo on
:MainMenu
@setlocal EnableDelayedExpansion
@set "Label=MainMenu"
@set /P "menu=Your choice: " || set "menu=2"
if "!menu!" == "1" set "Label=Label1"
if "!menu!" == "2" set "Label=Label2"
endlocal & goto %Label%

:Label1
@echo Option 1 was chosen, fine.
exit /B

:Label2
@echo Option 2 was chosen, okay.

Now the user input string does not modify anymore the command lines executed by Windows command processor. So an exit of batch file processing because of a syntax error caused by user input is not possible anymore (fail safe). Furthermore, the batch file never executes commands not written in batch file (secure).


3. Usage of CHOICE for a choice prompt

There is a better command than set /P for a simple choice menu – CHOICE.

@echo off
:MainMenu
cls
echo/
echo    1 ... Option 1
echo    2 ... Option 2
echo    E ... Exit
echo/
%SystemRoot%\System32\choice.exe /C 12E /N /M "Your choice: "
if errorlevel 3 exit /B
if errorlevel 2 goto Label2
if not errorlevel 1 goto MainMenu

@echo Option 1 was chosen, fine.
exit /B

:Label2
@echo Option 2 was chosen, okay.

The user has no freedom anymore to enter something not defined by batch file author. The batch file continues immediately after the user has pressed either 1, 2, E or Shift+E. Everything else is ignored by choice with exception of Ctrl+C.

The dynamic variable ERRORLEVEL has with three options nearly always a value in range 1 to 3 after choice terminated with returning 1 to 3 as exit code to calling cmd.exe. The exception is the rare use case that the user of a batch file pressed Ctrl+C on prompt and answers the next prompt Terminate batch job (Y/N)? of cmd.exe with N. In this case the dynamic variable ERRORLEVEL has the value 0 which is the reason for if not errorlevel 1 goto MainMenu to handle also this very special use case.

Note: if errorlevel X means IF GREATER OR EQUAL X. So it is always necessary to start with highest possible exit code of command choice.

As the exit code assigned to ERRORLEVEL is well known, it is possible on larger menus to optimize the code further by using appropriate labels:

@echo off
:MainMenu
cls
echo/
echo    1 ... Option 1
echo    2 ... Option 2
echo    E ... Exit
echo/
%SystemRoot%\System32\choice.exe /C 12E /N /M "Your choice: "
goto Label%ERRORLEVEL%

:Label0
rem The user pressed Ctrl+C and on next prompt N and
rem so made no choice. Prompt the user once again.
goto MainMenu

:Label1
@echo Option 1 was chosen, fine.
exit /B

:Label2
@echo Option 2 was chosen, okay.
exit /B

:Label3

The usage of command CHOICE can make choice menus very simple to code.

See also: How can I make an “are you sure” prompt in a Windows batch file?

Hint 1: There is a beep sound output by CHOICE if the user presses a not acceptable key. It is not possible to suppress that beep as there is no option offered by CHOICE to avoid output of the beep sound.

Hint 2: See also my answer on Where does GOTO :EOF return to? explaining also exit /B.

Leave a Comment