Search code examples
batch-fileuser-input

User input not recognized first time its prompted, windows batch


I'm currently trying to make a simple batch file that will check if i have Node.js installed, if i do it will tell me the version and if i dont i will get prompted to install via a local install file. Here's the code:

@echo off

set "output=0"
for /f "delims=" %%i in ('node -v 2^>nul') do set output=%%i

if %output%==0 (
echo Node not installed.

:start
SET /p choice=Would you like to installed Node? [Y/N]: 
IF '%choice%'=='Y' GOTO yes
IF '%choice%'=='y' GOTO yes
IF '%choice%'=='N' GOTO no
IF '%choice%'=='n' GOTO no
ECHO "%choice%" is not valid
ECHO.
GOTO start

:no
ECHO Not installing Node.
PAUSE
EXIT

:yes
ECHO Installing node...
CALL node-v16.15.0-x64.msi
ECHO Installed Node version:
CALL node -v
PAUSE
EXIT

) else (
echo Installed Node version:
call node -v
) 
pause

When running the bat file on a pc were node is not installed it'll prompt the use to input a Y or N. Regardless of what the user inputs the first time the input will always be empty (as in ""), then it will GOTO start once more and this time around the user input is acknowledged as whatever the input was, proceeding to GOTO whatever choice the user has inputted.

I cannot wrap my head around whatever might be causing this at the moment, ive not worked with batch files before. I've tried to find answers online but i do not know how to search for this issue since i am not familiar with what stuff is called or referred to as. Any help is appreciated.

EDIT: If i isolate the user input scenario in the code it seems to acknowledge the user input correctly. Essentially if i were to not check for a Node install and just run the user input, it works. Seems to be the case that the Node install check is impacting the user input.


Solution

  • You have two main issues:

    1. The lack of delayedexpansion (I initially closed it as duplicate, but realized you'll still have issues, without explanations)

    2. You cannot goto labels inside of a code block. You however do not need any of the above if you change your logic a bit. We'll use choice as the tool for choice menus. Then, no need to use a for loop as you can simply revert to the errorlevel of the command node -v:

    @echo off
    
    node -v && goto :VER || echo Node not installed
    
    choice /c YN /M "Install Node?"
    if errorlevel 2 (
        echo Not installing Node.
        pause
        exit /b
    )
    
    echo Installing node...
    call node-v16.15.0-x64.msi
    
    :VER
    echo Installed Node version:
    call node -v
    
    pause