batch - request user input depending on initial user input - windows

In Windows batch, I'm asking the user whether he wants to use the program's internal default or wants to set his own parameters, but no matter what the user sets as an answer, the program always jumps straight to the main routine using the internal defaults. This is my code:
#echo off
setlocal EnableDelayedExpansion
choice /C:yn /M "Use internal defaults? "
if errorlevel==1 goto yes
if errorlevel==2 goto no
rem use default
:yes
set "MYNUMBER=5"
goto run
rem let user define another number
:no
set /P MYNUMBER="Please set a number: "
goto run
rem main routine
:run
echo %MYNUMBER%
pause
What am I missing?
And since we're at it: how can I force the program to wait for the user to hit "Enter" after typing his choice? Right now, it starts directly after typing "y" or "n".

Thanks to the commentators, that helped a lot! Now its working like this:
#echo off
setlocal EnableDelayedExpansion
:ask
set /P USER_CHOICE="Use internal defaults? (Y/N) "
if /i "%USER_CHOICE%"=="y" (
goto yes
) else (
if /i "%USER_CHOICE%"=="n" (
goto no
) else (
echo "Wrong input! Please choose Y or N!"
goto ask
)
)
rem use default
:yes
set "MYNUMBER=5"
goto run
rem let user define another number
:no
set /P MYNUMBER="Please set a number: "
goto run
rem main routine
:run
echo %MYNUMBER%
pause

Related

Why is CMD prompt stating "set was unexpected at this time"

I'm trying to make a username change option for the settings in one of my batch file programs, but it keeps displaying a message like "set was unexpected at this time" which is weird, because my code seems right. It happens after entering a value for "cuser". None of the values I'm entering for input are null, since I've pre-declared the values at the beginning of the program to make it so I didn't have any null-value errors.
:uch
cls
echo.
echo Are you sure you want to change your username?
echo.
echo [Y/N]
echo.
set /p input=
if %input% EQU n goto set
if %input% NEQ y goto uch
:ucy
cls
echo.
echo Enter your current username
echo.
set /p cuser=
if %cuser% NEQ %username1% (
echo.
echo Incorrect username. Please try again.
echo Press any button to continue.
echo.
pause>null
goto :ucy
)
if %cuser% EQU %username1% (
echo Please enter new username.
echo.
set /p nuser=
echo Please enter again.
echo.
set /p nuser2=
if %nuser2% EQU %nuser% set username1=%nuser%
if %nuser2% EQU %nuser% goto ga1
if %nuser2% NEQ %nuser% (
echo Usernames do not match. Please try again.
echo Press any button to continue.
echo.
pause>null
goto ucy
)
goto ucy
You are trying to set value of variable inside if block without delayed expansion and the if is parsed with wrong syntax.And you have one unclosed bracket...
:uch
cls
echo.
echo Are you sure you want to change your username?
echo.
echo [Y/N]
echo.
set /p input=
if %input% EQU n goto set
if %input% NEQ y goto uch
:ucy
cls
echo.
echo Enter your current username
echo.
set /p cuser=
if %cuser% NEQ %username1% (
echo.
echo Incorrect username. Please try again.
echo Press any button to continue.
echo.
pause>null
goto :ucy
)
setlocal enableDelayedExpansion
if %cuser% EQU %username1% (
echo Please enter new username.
echo.
set /p nuser=
echo Please enter again.
echo.
set /p nuser2=
if !nuser2! EQU !nuser! set username1=!nuser!
if !nuser2! EQU !nuser! goto ga1
if !nuser2! NEQ !nuser! (
echo Usernames do not match. Please try again.
echo Press any button to continue.
echo.
pause>null
goto ucy
)
goto ucy
You are not using the proper syntax for the if command. When comparing strings, use
if "%var1%"=="%var2%" to compare. EQL NEQ etc. are for numeric comparison.
You DO NOT need to have multiple if statements (one for yes and one for no) because, you can assume that if they didn't say yes then they meant to say no. Here is an improved script for you, one that doesn't need delayed expansion in order to work. Hope this helps.
:uch
cls
echo.
echo Are you sure you want to change your username?
set /p input=[Y/N]
if not "%input%"=="y" (goto ga1)
::THEY WANT TO CHANGE THEIR USERNAME
cls
echo.
set /p cuser=Enter your current username ^>
if not "%cuser%"=="%username1%" (
echo.
echo Incorrect username. Please try again.
echo Press any button to continue.
pause>NUL
goto :uch
)
::THE USERNAME MATCHES
echo.
set /p nuser=Please enter new username. ^>
echo.
set /p nuser2=Please enter again. ^>
if "%nuser2%"=="%nuser%" (set username1=%nuser% && goto ga1)
echo Usernames do not match. Please try again.
echo Press any button to continue.
echo.
pause>NUL
goto uch
:ga1
:://DO SOME OTHER STUFF HERE AFTER THEY CHANGED THEIR NAME OR OPTED NOT TO.

Bat file to run default program

Is there a way to write a .bat file which sends all my inputs to a program running in background ?
Something like this ,
c:\start.bat
Opens a new prompt ,
But whatever I type in new prompt should go to the default program running in the background (Don't know where to specify the default program , I don't want to show the program name each time I pass the arguments). I want to use something like this line ,
<CUSTOM_PROMPT>"select data from tablex" , the string should go the "programX.bat"
instead of
<CUSTOM_PROMPT>programX.bat "select data from tablex"
I am afraid your question is not clear; there are many details that needs clarification. However, the Batch file below may give a starting point of discussion for both of us:
#echo off
setlocal
if "%~1" equ "goto" goto %2
cls
echo I am the user-interface program
echo Enter "exit" (with no quotes) to end
echo/
"%~F0" goto getInput | "%~F0" goto background > background.txt
echo/
echo The user-interface program ends
echo/
echo This is the input captured by background program:
echo/
type background.txt
goto :EOF
:getInput
set /P "input=<CUSTOM_PROMPT>: " > CON
echo %input%
if /I "%input%" neq "exit" goto getInput
goto :EOF
:background
set /P input=
if /I "%input%" equ "exit" goto :EOF
echo Input received at %time%:
echo %input%
echo/
goto background

Using FOR loop to move files into another directory

What I am trying to do:
Prompt the user to enter an account number.
The account number is the their folder.
The user is then prompted to select another directory (their time-stamped folder).
The script will then kick off an executable.
There will then be the parsing for findstr in a log file.
If the string comes back that it exists, then the script will then goto the :move sub-routine to attempt to recursively move through the "time-stamped" directory that the user selected to move all "*.ARC" files into their "Media1" folder.
The issue I am having is that the final step of running the for loop command in the "sub routine" :move is outputting the following error:
The filename, directory name, or volume label syntax is incorrect.
The filename, directory name, or volume label syntax is incorrect.
I'm not sure what is going on here as I can input this into a command prompt (without the !variables!) and get it to work. However, using the variables doesn't seem to work.
Another interesting point is that I am basically using the same !variables! under the :string "sub routine" and it finds exactly what I asked it to. So, I'm thinking there is nothing wrong with the !variables!?
Am I missing something here?
:main
cls
echo.
set /P acct=Please type the 9 digit account number you would like to restore:
set acctDir=x:\!acct!
set acctDir2=media1\Setup\setup.exe /cd
set log=c:\log.txt
echo. Starting on !date! !time! on !Computername! >> !log!
echo.
echo The account number you selected is: !acct!
echo.
goto :user
:user
set /p answer=Is this correct (Y/N)?
echo.
if /i !answer!==y goto :yes (
) else (
echo.
echo Ok. Let's try again^^!
echo.
pause
cls
goto :main
)
)
:yes
set c=0
For /f %%a in ('dir !acctDir! /B /A:D') do (
set /a c+=1
echo !c! %%a
set dir!c!=%%a
)
echo.
set /p userIn="Select a directory [1-!c!]: "
set userDir=!dir%userIn%!
echo.
echo You selected !userDir! for your data retrieval.
echo.
goto :string
:execute
echo.
echo The Data Protector Program will now be initialized...
start !acctdir!\!userDir!\!acctDir2!
goto :string
:string
set sumLog=!acctdir!\!userDir!\SummaryLog.txt
set succ=finished
set acctDir3=media1
set x=x:\!acct!\!userDir!
findstr " .*!succ!" !sumLog!
if exist errorlevel 0 (
pause
goto :move
) else (
goto :eof
)
:move
for /r "!acctdir!\!userDir!\" %%g in (*.ARC) do echo move "%%g" "!acctdir!\!userdir!\!acctdir3!\"
if exist errorlevel 1 (
echo Cannot move files. Error occurred.
pause
)
endlocal
goto :eof
Here is another tack to test your variables.
Add the four lines below after the :move label and run your batch file.
If there are any spaces or illegal characters you will see them there before the first pause.
:move
echo "!acctdir!"
echo "!userDir!"
echo "!acctdir3!"
pause
for /r "!acctdir!\!userDir!\" %%g in (*.ARC) do echo move "%%g" "!acctdir!\!userdir!\!acctdir3!\"
pause

How to handle input arugments to Batch file?

I'm trying to handle an input argument when I do call script.bat argument
If argument is missing, the receiving script.bat will pop a prompt to ask user to assign value. But right now even if I do script.bat number, the prompt shows up anyway...not sure why.
Code:
:Loop
IF "%1"=="" GOTO Prompt
set VAR=%1
SHIFT
GOTO Loop
:Prompt
set /p VAR="Check which value? "
GOTO Continue
:Continue
You need to skip the :Prompt if the argument was supplied correctly:
:Loop
IF "%1"=="" GOTO Prompt
SET VAR=%1
GOTO Continue
SHIFT
GOTO Loop
:Prompt
set /p VAR="Check which value? "
GOTO Continue
:Continue
Actually, you can now remove the SHIFT and GOTO Loop; as #dbenham posted in the comment below, it's unreachable code. This also eliminates the :Loop itself, as it is never used. This reduces it to:
IF "%1"=="" GOTO Prompt
SET VAR=%1
GOTO Continue
:Prompt
set /p VAR="Check which value? "
GOTO Continue
:Continue
If %1 is set, you have to go to your continue label.
The accepted Ken White solution will work, but it can be greatly simplified.
set "VAR=%~1"
if not defined VAR set /p "VAR=Check which value? "
The user could simply press <Enter> without entering anything. You could introduce a GOTO loop to enforce entry of a value.
set "VAR=%~1"
:loop
if not defined VAR set /p "VAR=Check which value? "&goto :loop

Ignoring Null or Enter in Batch

I am running a batch file that prompts the user to "enter name". If the user entered nothing and pressed enter, then I want to show the same window over and over again that says:
Enter Name:
The below code is not working:
#echo off
:myDosFunc
set /p name=Enter Name:
IF "%name%"=="" (
call:myDosFunc
) ELSE (
echo %path%
)
pause
GOTO:EOF
call:myDosFunc
I am new to batch, please help.
This is similar to the w0051977 answer, but I belive it more closely matches your original intent.
#echo off
set "name="
:myDosFunc
set /p "name=Enter Name: "
if not defined name goto :myDosFunc
echo %path%
pause
exit /b
If you only want the prompt to appear once, no matter how many times the user presses Enter without entering anything, then you can use:
#echo off
set "name="
<nul set /p "=Enter Name: "
:myDosFunc
set /p "name="
if not defined name goto :myDosFunc
echo %path%
pause
exit /b
I think this is what you are after:
#ECHO OFF
:start
SET /P uname=Please enter your name:
IF "%uname%"=="" GOTO Error
ECHO Hello %uname%, Welcome to DOS inputs!
GOTO End
:Error
goto start
:End
Use the GOTO keyword. Go here for more information: http://www.codeproject.com/Tips/123810/Get-user-input-from-DOS-prompt
The problem is that you are trying to show the PATH without enclosing it with double quotes, and PATH can contain conflictive operators like ) then the batfile closes by an error.
PS: I've made other minor corrections in the code.
#echo off
:myDosFunc
Set "NAME="
set /p "name=Enter Name:"
IF NOT DEFINED NAME (
call :myDosFunc
) ELSE (
echo "%path%"
)
pause
GOTO:EOF
A simple solution would be to add cls before you prompt for the input
:myDosFunc
cls
set /p name=Enter Name:

Resources