I'm creating a batch menu in MS-DOS 6.22 and I need to use if errorlevel
with mixed goto
and call
commands. I'm having some issues with the order because they are not executed as expected.
I can't start the other batch files without using call
with the exception of file6.bat
because I need to preserve environment variables.
This is an example of the menu:
:MENU
@echo off
echo [1] Choice 1
echo [2] Choice 2
echo [3] Choice 3
echo [4] Choice 4
echo [5] Choice 5
echo [6] Choice 6
echo [7] Choice 7
echo [8] Choice 8
echo [Y] Choice Y
echo [Z] Choice Z
choice /c12345678YZ /n /m "Select an option"
if errorlevel 10 call file7.bat
if errorlevel 9 file6.bat
if errorlevel 8 call file5.bat
if errorlevel 7 call file4.bat
if errorlevel 6 call file3.bat
if errorlevel 5 call file2.bat
if errorlevel 4 goto menu3
if errorlevel 3 goto menu2
if errorlevel 2 goto menu1
if errorlevel 1 call file1.bat
That's the behaviour:
goto menu3
].Could you please help me understand how to fix this problem?
Three facts are important here:
COMMAND.COM
of MS-DOS 6.22 processes one line after the other from top to bottom of a batch file, except the command GOTO is used to continue batch file processing not on next line, but on line below the line with the label specified as parameter for command GOTO.
The DOS command processor continues processing of a batch file on another batch file without returning ever back to current batch file if the other batch file is specified on a command line without usage of command CALL.
The condition if errorlevel X
means IF ERRORLEVEL IS GREATER OR EQUAL 1. It is necessary to use two conditions to check if exit code of a command or application is equal a specific number. The necessary syntax is: if errorlevel X if not errorlevel X+1 command
. That is like IF ERRORLEVEL IS EQUAL X because of ERRORLEVEL must be GREATER OR EQUAL X AND LESS THAN X+1. These two conditions are only true IF ERRORLEVEL IS EQUAL X. Example: if errorlevel 6 if not errorlevel 7 call file3.bat
results in calling file3.bat
only IF ERRORLEVEL IS EQUAL 6.
Let us look together on the use cases defined by the key pressed by the user.
Use case 1: The user presses key Z.
CHOICE.COM
exits with value 10
assigned to ERRORLEVEL
.if errorlevel 10
is true and therefore batch file file7.bat
is called by command processor.COMMAND.COM
continues on next IF condition line after finishing processing of file7.bat
, except it contains the command EXIT which results in exiting the command process independent on the calling hierarchy on being really executed.if errorlevel 9
evaluates not the exit code of CHOICE.COM
, but the exit code returned by batch file file7.bat
to the main batch file. The exit code returned by file7.bat
is most likely 0
and therefore this second condition and all other below are evaluating to false.Use case 2: The user presses key Y.
CHOICE.COM
exits with value 9
assigned to ERRORLEVEL
.if errorlevel 10
is false.if errorlevel 9
is true resulting in execution of file6.bat
. The command CALL is not used here. For that reason COMMAND.COM
does not return back to main batch file after finishing processing of file6.bat
. For that reason everything below if errorlevel 9 file6.bat
does not matter on this condition being true because of batch file processing ends with finishing processing of file6.bat
.Use case 3: The user presses key 8.
CHOICE.COM
exits with value 8
assigned to ERRORLEVEL
.if errorlevel 10
is false.if errorlevel 9
is false.if errorlevel 8
is true and therefore batch file file5.bat
is called by command processor.COMMAND.COM
continues on next IF condition line after finishing processing of file5.bat
, except it contains the command EXIT and which is also executed.if errorlevel 7
evaluates the exit code returned by batch file file5.bat
to the main batch file which is most likely 0
and therefore this fourth condition and all other below are evaluating to false.The behavior is more or less the same on user pressing key 7, 6 or 5.
Use case 4: The user presses key 4.
CHOICE.COM
exits with value 4
assigned to ERRORLEVEL
.if errorlevel 4
is true and therefore command GOTO is executed resulting in continuation of batch file processing on the line below the line with the label menu3
. So the other IF conditions do not matter on this use case.The behavior is more or less the same on user pressing key 3 or 2.
Use case 5: The user presses key 1.
CHOICE.COM
exits with value 1
assigned to ERRORLEVEL
.if errorlevel 9
is true and therefore batch file file1.bat
is called by command processor.COMMAND.COM
continues on line after finishing processing of file1.bat
, except the command EXIT is executed during processing of file1.bat
.There are at least three potential problems with this code:
ERRORLEVEL
like called batch file containing only a series of set variable=value
, the next IF condition below the IF condition resulting in calling the other batch file is also true which results in calling one more batch file or continuation of batch file processing on code for menu3
.if errorlevel 1
determines what happens next on any other batch file called from within this main batch file in case of all those batch files exit with value 0
.The third problem can be easily solved by writing next in main batch file after last condition if errorlevel 1
either goto MENU
to continue batch file processing at top with printing again the menu or goto ENDBAT
with last line in main batch file being :ENDBAT
to continue processing the batch file at end of the batch file which means finishing the processing of this batch file.
But it is necessary for the potential problems 1 and 2 to make sure that processing of main batch file continues not on next command line after calling other batch file, but for example with the menu.
@echo off
:MainMenu
cls
echo [1] Choice 1
echo [2] Choice 2
echo [3] Choice 3
echo [4] Choice 4
echo [5] Choice 5
echo [6] Choice 6
echo [7] Choice 7
echo [8] Choice 8
echo [Y] Choice Y
echo [Z] Choice Z
choice /C:12345678YZ /N /M "Select an option:"
if errorlevel 10 set BatFile=7
if errorlevel 9 if not errorlevel 10 file6.bat
if errorlevel 8 if not errorlevel 9 set BatFile=5
if errorlevel 7 if not errorlevel 8 set BatFile=4
if errorlevel 6 if not errorlevel 7 set BatFile=3
if errorlevel 5 if not errorlevel 6 set BatFile=2
if errorlevel 4 if not errorlevel 5 goto Menu3
if errorlevel 3 if not errorlevel 4 goto Menu2
if errorlevel 2 if not errorlevel 3 goto Menu1
if errorlevel 1 if not errorlevel 2 set BatFile=1
call file%BatFile%.bat
set BatFile=
goto MainMenu
:Menu3
echo Here would be shown menu 3.
goto ENDBAT
:Menu2
echo Here would be shown menu 2.
goto ENDBAT
:Menu1
echo Here would be shown menu 1.
goto ENDBAT
:ENDBAT
The goal for every called batch file is to continue with showing again the main menu after finishing processing of called batch file. For that reason it is enough to define an environment variable like BatFile
with the number of the batch file to call and make sure that always only one IF condition is true according to errorlevel
set by CHOICE.COM
.
The code above results in execution of file6.bat
on user pressing key Y with ignoring the remaining lines in this main batch file. The batch file processing continues with pressing key 2, 3 or 4 on appropriate code for the submenu 1, 2 or 3. But for the keys 1, 5 to 8 and 7 is called the appropriate batch file, then defined environment variable BatFile
is undefined and batch file processing continues with printing again the main menu and let the user take one more choice.
It is of course also possible to assign complete file name of the batch file to call to environment variable BatFile
instead of just its number if the batch files to call have different file names and just file extension is the same for all batch files to call. In this case the command line with CALL would be call %BatFile%.bat
.