batch-filedynamicbatch-choice

How to save user input from CHOICE command to a variable to be used later in the errorlevel


I have a dynamic list of choices for a program I'm writing. I have it working correctly so that it will change the CHOICE options based on the count variable but now I'm struggling with making the errorlevel dynamic as well. Here is my code:

SETLOCAL EnableDelayedExpansion
@ECHO off
SET count=7
SET ph=
FOR /L %%a IN (1,1,%count%) DO (
SET ph=!ph!%%a
ECHO !ph!
)
CHOICE /C Q%ph%
IF errorlevel (I don't have a variable for this) (
echo "in if" & pause
)

IF errorlevel 1 echo "out of if" & pause

My idea is to set the errorlevel equal to what the user put in (e.g. the user puts in 7 as their choice, the errorlevel becomes 7) The reason I want to do this is because I need the errorlevel to pass for everything besides 1, which is reserved for a quit option (which is why I have the "Q" there) Any advice and suggestions are much appreciated! Thanks!


Solution

  • I suggest following batch code for this task:

    @ECHO OFF
    SETLOCAL EnableExtensions EnableDelayedExpansion
    SET count=7
    SET ph=
    FOR /L %%a IN (1,1,%count%) DO SET ph=!ph!%%a
    %SystemRoot%\System32\choice.exe /C Q%ph%
    IF NOT ERRORLEVEL 2 ECHO Bye^^!& GOTO :EOF
    SET /A UserChoice=%ERRORLEVEL%-1
    ECHO You have chosen %UserChoice%.
    PAUSE
    

    IF NOT ERRORLEVEL 2 means if the exit code of CHOICE is NOT GREATER OR EQUAL 2 which is the same as if LESS THAN 2 then execute ECHO and GOTO to exit processing of this batch file.

    The command IF does not modify value of ERRORLEVEL as documented at
    What are the ERRORLEVEL values set by internal cmd.exe commands?

    It would be also possible to first assign the exit code of CHOICE to an environment variable decremented by 1 and then make the comparison for quit by comparing the value with 0.

    @ECHO OFF
    SETLOCAL EnableExtensions EnableDelayedExpansion
    SET count=7
    SET ph=
    FOR /L %%a IN (1,1,%count%) DO SET ph=!ph!%%a
    %SystemRoot%\System32\choice.exe /C Q%ph%
    SET /A UserChoice=%ERRORLEVEL%-1
    IF %UserChoice% == 0 ECHO Bye^^!& GOTO :EOF
    ECHO You have chosen %UserChoice%.
    PAUSE
    

    It is not advisable to use an environment variable with name choice as it makes it difficult to search for this environment variable in a batch file containing also external command CHOICE which is the reason for using UserChoice.

    The command CHOICE is specified with full qualified file name (file path + file name + file extension) for safety reasons. Windows command processor does not need to search for choice.* with a file extension listed in environment variable PATHEXT in current directory and the directories listed in local environment variable PATH on using full qualified file name. This makes the batch file robust against corrupted system PATH containing the path of a folder before most important folder path %SystemRoot%\System32 which by chance contains also a choice.* file with a file extension listed in PATHEXT. The local environment variable PATH does not need to exist at all on running this batch file because of using full qualified file name of executable CHOICE. It also does not matter with full qualified file name if a user created a batch file with name choice.bat or choice.cmd in the directory being the current directory on running this batch file or any other directory in PATH being searched by cmd.exe before %SystemRoot%\System32.