1

I've written the following windows batch script for WinPE to make some tasks easier:

@ECHO OFF
CLS

:MENU
SETLOCAL
SET QUIT=FALSE
SET /P INPUTCHOICES=Type 1, 2, 3 or 4 and press ENTER: 
CALL :EXECUTECHOICES %INPUTCHOICES%
ENDLOCAL

GOTO :EOF

:EXECUTECHOICES
IF [%1]==[] (GOTO :MENU) ELSE (CALL :%1)
SHIFT
GOTO :EXECUTECHOICES

GOTO :EOF

:1
cls
SET /P RB_OR_SD=Type R to reboot or type S to shutdown your PC when done, and press ENTER: 
ECHO Performing task 1
ECHO.
pause
IF "%RB_OR_SD%"=="R" (GOTO :3)
IF "%RB_OR_SD%"=="S" (GOTO :4)
ELSE (GOTO :3)

:2
cls
SET /P RB_OR_SD=Type R to reboot or type S to shutdown your PC when done, and press ENTER: 
ECHO Performing task 2
ECHO.
pause
IF "%RB_OR_SD%"=="R" (GOTO :3)
IF "%RB_OR_SD%"=="S" (GOTO :4)
ELSE (GOTO :3)

:3
cls
ECHO The system will now reboot
ECHO.
pause
GOTO :MENU

:4
cls
ECHO The system will now shutdown
ECHO.
pause
GOTO :MENU

GOTO :EOF

This script seems to be working fine, until the user inputs anything other than 1, 2, 3, 4, R or S.

In case of INPUTCHOICES any wrong symbol just leads to "The system cannot find the batch label specified" message and the prompt reloads.

But in case of putting anything other than R or S into RB_OR_SD the script just executes the next available batch label, which is absolutely not OK.

I want to limit the user input with exactly one symbol from the scope of 1, 2, 3 and 4 for the INPUTCHOICES, and from the scope of R and S for the RB_OR_SD.

Preferably making the user input case-insensitive.

Any help would be highly appreciated.

YKKY
  • 605
  • 1
  • 6
  • 18
  • Read the help of `if /?` and particularly study the part with the `if`/`else` syntax, which you are doing wrong. Anyway, you actually do not need `else` here, just state `goto :3` after the `if` queries. By the way, do not use labels like `:1`, `:2`, `:3`, use meaningful names like `:Task1`, `:Task2`, `:ErrorCase`... – aschipfl Oct 09 '18 at 13:54
  • How will this limit user input? – YKKY Oct 09 '18 at 13:56
  • 2
    I guess, you will appreciate the [choice](https://ss64.com/nt/choice.html) command – Stephan Oct 09 '18 at 13:57
  • Use the command `CHOICE /?` for more information. – lit Oct 09 '18 at 20:27

2 Answers2

0

I'm not completely sure I understand what you're trying to achieve, but I think this might be able to help you:

:MENU
CLS
SETLOCAL
SET QUIT=FALSE
SET /P INPUTCHOICES=Type 1, 2, 3 or 4 and press ENTER:
CALL :VALIDATOR
ENDLOCAL

:validator
call :check 1
call :check 2
call :check 3
call :check 4
call :check "R"
call :check "S"
GOTO MENU

:check
IF %INPUTCHOICES% == %~1 ( CALL :EXECUTECHOICES %INPUTCHOICES% )
exit /b 0
  • Thanks for your response. I'm just trying to prevent the user (myself actually) to press any key or their combination other than the ones that execute commands listed in menu. How I miss old ms-dos times where I could define the menu items in config.sys and have selectable menu in autoexec.bat ;) – YKKY Oct 18 '18 at 20:33
0

Just restricting myself to answering your question, without any changes/edits to your code...

Use findstr to check if input:

if [length == 1]  /be [begin/end]  with one number [1,2,3,4] and operator || == return non 0 

setlocal EnableDelayedExpansion

:menu
cls & setlocal & set "_quit=false"
set /p "_input=type 1, 2, 3 or 4 and press enter: " || goto :menu
<con: echo\%_input%| 2>nul %__AppDir__%findstr.exe/be [1-4] >nul || goto :menu

the command here only execute if findstr command return 0

If input fail goto :menu If input is not in ranger 1-4 goto :menu

Similar you can do with r b case-insensitive:

setlocal EnableDelayedExpansion

:menu
cls & setlocal & set "_quit=false"
set /p "_input=type r or s and press enter: " || goto :menu
<con: echo\%_input%| 2>nul %__AppDir__%findstr.exe/be "r s" >nul || goto :menu

the command here only execute if findstr command return 0

@ECHO OFF

CLS
cd /d "%~dp0"
SetlocaL EnableDelayedExpansion

:MENU
SET "QUIT=FALSE"
set "INPUTCHOICES="

2>nul (
SET /P "INPUTCHOICES=Type: 1, 2, 3 or 4 & press [ENTER] "
) || goto :MENU 

2>nul (
echo\!INPUTCHOICES!| findstr /rbe [1-4] >nul
) || goto :MENU 

for /l %%i in (1 1 4)do if %%i equ !INPUTCHOICES! CALL :%%i

ENDLOCAL

GOTO :EOF

:1
cls
set "RB_OR_SD="

2>nul (
SET /P "RB_OR_SD=Type R to reboot or type S to shutdown your PC when done, and press ENTER: "
) || goto :1

2>nul (
echo\!RB_OR_SD!| findstr /be "R S" >nul
) || goto :1

ECHO Performing task 1
ECHO.
pause
IF "%RB_OR_SD%"=="R" (GOTO %:^3)else GOTO %:^4

:2
cls
set "RB_OR_SD="

2>nul (
SET /P "RB_OR_SD=Type R to reboot or type S to shutdown your PC when done, and press ENTER: "
) || goto :2

2>nul (
echo\!RB_OR_SD!| findstr /be "R S" >nul
) || goto :2

ECHO Performing task 2
ECHO.
pause
IF "%RB_OR_SD%"=="R" (GOTO %:3)else GOTO %:4

:3
cls
ECHO The system will now reboot
ECHO.
pause
GOTO :MENU

:4
cls
ECHO The system will now shutdown
ECHO.
pause
GOTO :MENU
Io-oI
  • 2,514
  • 3
  • 22
  • 29