So, I created a program, which can create and delete folders on the desktop. And I have a problem, when I just write a single space for the name I got the error "Please write a valid folder name!" so it works, but if I'm using more than one spaces, it says "Folder created successfully", and I want to make this program to make an error when I only using spaces in the folder's name. Please help!
Here's a part of my code (the full code is 132 lines long)
set Choice=
set /p Choice="Choose an option: "
if '"%Choice%"'=='"1"' goto masodik
if '"%Choice%"'=='"2"' goto negyedik
if '"%Choice%"'=='"3"' goto otodik
if '"%Choice%"'=='"4"' goto harmadik
if not '"%Choice%"'=='"1"' goto hiba2
if not '"%Choice%"'=='"2"' goto hiba2
if not '"%Choice%"'=='"3"' goto hiba2
if not '"%Choice%"'=='"4"' goto hiba2
:masodik
cls
echo Create a folder
echo ---------------
echo.
cd "%systemdrive%/documents and settings/%username%/desktop"
echo Enter the folder's name!
echo.
set /p mappaneve="The folder's name: "
if "%mappaneve%" EQU "" goto hiba
if EXIST "%mappaneve%" goto hiba3
md "%mappaneve%"
cls
echo Create a folder
echo ---------------
echo.
echo Successfully created "%mappaneve%"!
timeout /t 3 >nul
cls
goto elso
if "%mappaneve: =%" EQU "" goto hiba
ie, replace all spaces with nothing and if the result is nothing then the input must have been all spaces (if that was what you were asking)
quotes is used in variable asignation to make sure space are handle correctly. don't include quotes inside your variable unless when you want to use it.try change your code into this.
set /p "mappaneve=The folder's name: "
Magoo posted the right code in his short answer.
Here is a much longer answer with commented batch code and additional explanations on the various improvements in this code in comparison to code in question post.
set "UserChoice="
set /p "UserChoice=Choose an option: "
if "%UserChoice%" == "1" goto masodik
if "%UserChoice%" == "2" goto negyedik
if "%UserChoice%" == "3" goto otodik
if "%UserChoice%" == "4" goto harmadik
rem None of the 4 valid numbers was entered.
goto hiba2
:masodik
rem Set current directory to desktop directory of current user.
cd /D "%USERPROFILE%\Desktop"
cls
echo Create a folder
echo ---------------
echo.
rem Define a double quote as default value to be able to remove all
rem double qotes from input string with no syntax error even if the
rem user just hits key RETURN or ENTER without entering any string.
set "mappaneve=""
set /p "mappaneve=Enter folder name: "
rem Remove all double quotes from entered folder name.
set "mappaneve=%mappaneve:"=%"
rem Check if user has entered anything at all and if entered folder name
rem does not exist of only 1 or more spaces by using environment variable
rem substitution which removes for string comparison all spaces from the
rem entered folder name.
if "%mappaneve%" == "" goto hiba
if "%mappaneve: =%" == "" goto hiba
rem Appending \* makes sure to test on existence of a folder and not a file.
rem It does not matter if entered folder name ends already with a backslash.
rem Does the folder already exist?
if exist "%mappaneve%\*" goto hiba3
rem Create the folder and verify if that was successful with
rem saving error message into a temporary file for output below.
md "%mappaneve%" 2>"%TEMP%\%~n0_FolderError.tmp"
if errorlevel 1 goto FolderError
rem On successful creation of the folder an empty file is
rem created which should be removed before processing further.
del "%TEMP%\%~n0_FolderError.tmp"
cls
echo Create a folder
echo ---------------
echo.
echo Created successfully "%mappaneve%".
timeout /t 3 >nul
cls
goto elso
:FolderError
cls
echo Failed to create folder "%mappaneve%".
echo.
echo Error message:
echo.
type "%TEMP%\%~n0_FolderError.tmp"
del "%TEMP%\%~n0_FolderError.tmp"
echo.
pause
The improvements are:
Comparing strings with command IF should be done with using surrounding double quotes only. The single quotes are removed from the 4 string comparisons.
Of course if the batch user enters for example "2" (number 2 with double quotes) the batch execution would be exited by command processor because of a syntax error caused by processing if ""2"" == "1" goto masodik. Using delayed variable expansion would be one solution for this issue.
The 4 lines with if not '"%Choice%"'==... can be replaced simply by goto hiba2 as they are all definitely true after the first 4 string comparisons.
choice (SS64 article) is a standard Windows command. Therefore it is advisable to avoid choice (Microsoft article) as name for an environment variable or label. UserChoice (CamelCase spelling for easier reading) is used instead of Choice.
Command choice would be a very good alternative for first user prompt because then the user can't enter something different than 1, 2, 3, or 4.
There is predefined by Windows the environment variable USERPROFILE containing path to the user´s profile directory containing the directory Desktop and other user account related directories. This variable should be used instead of building path with other variables.
The directory separator on Windows is the backslash character and not the forward slash character. Windows supports in the meantime also directory paths with / instead of \, but it is nevertheless better to use the right directory separator.
The user´s profile directory can be on a different drive than system drive. Or the drive from which the batch file is executed is a different one than the drive of user´s profile directory. Therefore it is advisable to use command CD with parameter /D as otherwise changing directory could fail if current drive is different to drive of user´s profile directory.
It is advisable to define a default for an environment variable before prompting a user or clearing the variable. The user can hit just RETURN or ENTER in which case the environment variable keeps its value.
This was done for Choice, but was forgotten for mappaneve.
The user could enter a folder name with double quotes. Therefore it is advisable to remove all double quotes from entered folder name as otherwise the batch script processing would be exited by command processor because of a syntax error on further processing the batch file.
To really test existence of a folder with if exist and not also a file, it is necessary to append \* to the folder name as otherwise if exist could be true also with user input string is name of an existing file.
Creation of folder could fail because of 1 or more invalid characters in folder name, a file exists with same name already, or the user does not have permission to create a folder.
The last reason is very unlikely here with current directory being the desktop directory of the user if user really enters just a folder name and not a directory path to create anywhere a directory (tree) which would be possible here, too.
So it is advisable to test on success on creating the folder.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
cd /?
cls /?
del /?
echo /?
goto /?
if /?
md /?
rem /?
set /?
timeout /?
type /?
And read also the Microsoft articles:
Testing for a Specific Error Level in Batch Files
Using command redirection operators
Related
I have tried to add a variable into an already existing batch file that I have written. However, when using the new command with the variable the command gets jumbled up.
How it supposed to work.
A user is prompted for an input (one of 3 letters). The input dictates the root directory used for a software execution. This section of code pulls a list of .elf files and is supposed to write them to a .txt file in the root directory.
Issue.
When using the variable directory, the .txt file and directory are switched during execution.
Original (Works)
DIR \\somepath\%VAR%\*.elf /b /o-s>C:\MyRootFolder\unlk.txt
New command with 2nd variable (acts strangely)
DIR \\somepath\%VAR%\*.elf /b /o-s>%root%\unlk.txt
but executes like this!?
DIR \\somepath\25091562033-00\*.elf /b /o-s \unlk.txt 1>C:\MyRootFolder
I am trying to have my root folder selected by an input further up because there are 3 different versions of software that I need to use to perform an operation. Being able to have the folder selected by an input would make things a lot easier.
Any ideas of why this executes semi-backwards?
Edit:
Here is the first section of my batch file all the way down to where the error happens. I have removed some of the code that doesn't relate to the issue. Note that the excessive pauses are for troubleshooting and the section which sets the variable %ECUPN% has been removed as it is working as intended.
ECHO off
:Ask
CLS
ECHO What type of processor does this ECU have?
ECHO F = Freescale_Quasar
ECHO T = TI
ECHO M = Motorola
SET INPUT=
SET /P INPUT=[F/T/M]: %=%
IF /I "%INPUT%"=="F" SET root=C:\Freescale_Quasar && GOTO :Fetch
IF /I "%INPUT%"=="T" SET root=C:\TI_MK100 && GOTO :Fetch
IF /I "%INPUT%"=="M" SET root=C:\MK100_Motorola && GOTO :Fetch
GOTO :Ask
:Fetch
CLS
Echo on
ECHO Fetch
pause
DIR \\mofs01p2.auto.contiwan.com\didf5076\FlashDataFiles\Flashline\%ECUPN%\*.elf /b /o-s>%root%\unlk.txt
pause
SET /P Code=<%root%\unlk.txt
pause
COPY "\\mofs01p2.auto.contiwan.com\didf5076\FlashDataFiles\Flashline\%ECUPN%\%Code%" "%root%\unlock.elf" || GOTO :error_1
pause
ECHO App = %code%>>C:\Unlock\log.txt
pause
GOTO :Build_1
I was able to create this batch file to move certain files from one folder to another. But I want to be able to use it also on different folders. For instance here I'm only moving files from UTS16. I want to use this batch file also for other folders like UTS15, UTS14, UTS13, UTS12, etc.
What do I need to change in code to ask the batch user on which folder to run? What am I missing?
#echo off
SET /P letter=Please give your drive letter and press ENTER:
ECHO %letter%
PAUSE
SET Datefolder="%date:~10,4%_%date:~4,2%_%date:~7,2%_%time:~0,2%%time:~3,2%"
MD "%Datefolder%"
mkdir %letter%:\UTS16\Database\"RTBackup%Datefolder%"
move /-y "%letter%:\UTS16\Database\*.dbf" "%letter%:\UTS16\Database\RTBackup%Datefolder%"
move /-y "%letter%:\UTS16\Database\*.cdx" "%letter%:\UTS16\Database\RTBackup%Datefolder%"
move /-y "%letter%:\UTS16\Database\*.~cd" "%letter%:\UTS16\Database\RTBackup%Datefolder%"
move /-y "%letter%:\UTS16\Database\*.~db" "%letter%:\UTS16\Database\RTBackup%Datefolder%"
move /-y "%letter%:\UTS16\Database\*.fpt" "%letter%:\UTS16\Database\RTBackup%Datefolder%"
move /-y "%letter%:\UTS16\Database\RTBackup%Datefolder%\zipdata.dbf" "%letter%:\UTS16\Database\"
pause
start "" %letter%:\UTS16/dbrepair.exe
I suggest for your task following commented batch file:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
goto UserPrompt
rem Define environment variable BaseFolder with a double quote character as
rem value in case of the user enters nothing on prompt in which case the
rem variable BaseFolder is still defined with the double quote as value.
rem Then let the user enter the folder path or drag and drop
rem the folder over the console window to enter the path.
rem Next remove all double quotes from folder path and test
rem if the variable BaseFolder still exists with a value.
rem Last replace forward slashes by backslashes in case of user entered
rem the path with forward slashes, make sure the folder path does not
rem end with a backslash and test if the folder really exists in case of
rem user has made a typing mistake on entering manually the folder path.
rem Run the backup and repair operation if entered folder exists as expected.
:UserPrompt
cls
echo/
echo Please type the database base folder path and press ENTER.
echo/
echo Or alternatively drag ^& drop the folder from Windows
echo Explorer on this console window and press ENTER.
echo/
set "BaseFolder=""
set /P "BaseFolder=Path: "
set "BaseFolder=!BaseFolder:"=!"
if "!BaseFolder!" == "" goto UserPrompt
set "BaseFolder=!BaseFolder:/=\!"
if "!BaseFolder:~-1!" == "\" set "BaseFolder=!BaseFolder:~0,-1!"
if "!BaseFolder!" == "" goto UserPrompt
echo/
if not exist "!BaseFolder!\Database\*" (
echo There is no folder "!BaseFolder!\Database".
echo/
choice "Do you want to enter the path once again "
if errorlevel 2 goto ExitBatch
goto UserPrompt
)
set "BackupFolder=%BaseFolder%\Database\RTBackup%DATE:~10,4%_%DATE:~4,2%_%DATE:~7,2%_%TIME:~0,2%%TIME:~3,2%"
rem For German date/time format which is for DATE TIME: dd.mm.yyy hh:mm:ss,xx
rem set "BackupFolder=%BaseFolder%\Database\RTBackup%DATE:~-4%_%DATE:~-7,2%_%DATE:~-10,2%_%TIME:~0,2%%TIME:~3,2%"
if exist "%BackupFolder%\*" goto MakeBackup
md "%BackupFolder%"
if errorlevel 1 (
echo/
echo Error: Failed to create backup folder !BackupFolder!
echo/
choice "Repair without making a backup "
if errorlevel 2 goto ExitBatch
goto RunRepair
)
:MakeBackup
echo Making a backup to folder !BackupFolder! ...
move /-y "%BaseFolder%\Database\*.dbf" "%BackupFolder%" 2>nul
move /-y "%BaseFolder%\Database\*.cdx" "%BackupFolder%" 2>nul
move /-y "%BaseFolder%\Database\*.~cd" "%BackupFolder%" 2>nul
move /-y "%BaseFolder%\Database\*.~db" "%BackupFolder%" 2>nul
move /-y "%BaseFolder%\Database\*.fpt" "%BackupFolder%" 2>nul
move /-y "%BackupFolder%\zipdata.dbf" "%BaseFolder%\Database\" 2>nul
:RunRepair
echo/
echo Running database repair ...
"%BaseFolder%\dbrepair.exe"
:ExitBatch
endlocal
Please read first answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? explaining the difference between set variable="value" and set "variable=value".
The environment variable Datefolder was created in batch file in question with double quotes included in environment variable value resulting in expanding
"%letter%:\UTS16\Database\RTBackup%Datefolder%"
for example to
"C:\UTS16\Database\RTBackup"2017_01_13_1250""
which of course is not good. Double quotes inside a double quoted string is in general not correct.
And the command line
mkdir %letter%:\UTS16\Database\"RTBackup%Datefolder%"
expanded for example to
mkdir C:\UTS16\Database\"RTBackup"2017_01_13_1250""
Error correction of Windows must do overtime to fix the folder paths.
The date/time format of the environment variables DATE and TIME depends on Windows region and language settings of current user. I needed a different line to define the backup folder with date and time in name for my German Windows machine. There are region independent solutions posted for example at How to get current datetime on Windows command line, in a suitable format for using in a filename? However, if the faster command line using the environment variable DATE and TIME work on the computers where this batch file is used, there is no need to replace that line with a region independent solution.
The batch file in this answer uses delayed expansion of environment variables mainly to prevent an exit of batch processing in case of user enters by mistake a path string which results without usage of delayed expansion in a syntax error.
The user can drag & drop the folder also for example from Windows Explorer over the console window to enter the folder path on prompt.
echo/ is used to output a blank line which is better than echo. as explained by DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/
The ampersand & is interpreted by Windows command interpreter as operator for executing multiple commands in one command line in an unquoted string. For that reason it is necessary to escape this character with the caret character ^ to be interpreted as literal character to echo into the console window. See Single line with multiple commands using Windows batch file for details on meaning of &, && and || in a command line in an unquoted string and not escaped with ^.
The command choice is used on asking if the user wants to proceed on error or exit the batch file. This command appends to prompt text in square brackets the keys to press for Yes or No in language of Windows and a question mark, i.e. [Y,N]? on English Windows or [J,N]? on German Windows. choice does not allow any other key before exiting. The exit code assigned to errorlevel is 2 on No and 1 on Yes.
The Microsoft support article Testing for a Specific Error Level in Batch Files explains the usage of if errorlevel to test on exit code of previous command or application. In this case it is enough to test on errorlevel being greater or equal 2 to exit batch processing on an error in case of user chooses No.
The batch file does not check if "%BaseFolder%\dbrepair.exe" really exists before it tries to execute this application. It would be good if that additional check with appropriate error message for the user is added, best before creating the backup folder.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
choice /?
cls /?
echo /?
endlocal /?
goto /?
if /?
md /?
move /?
set /?
setlocal /?
And read also the Microsoft TechNet article Using command redirection operators for an explanation of 2>nul.
Is this the proper way to write these lines of batch code with the exceptions of spaces and unneeded percent signs?
:name
cls
echo now that we've got your color figured out, what about your name?
echo simply type the name you want for your character into the space below
echo (6 char max)
echo.
set /p %player% =
cls
echo so you want your name to be %player% ?
echo.
echo 1) yes
echo 2) no
set /p %namechoice% =
if %namechoice% == 1 goto check
if %namechoice% == 2 goto name
:check
if /I %player% == %username% (goto gamestart) else goto suprise
:suprise
The player name is not output after batch user entered it.
And the string comparisons with check and name are also not working.
The command line if %namechoice% == 1 goto check results in break of batch file execution with error message:
goto was unexpected at this time.
The main mistake is a simple syntax issue:
Environment variables are defined with just specifying the variable name without percent signs and with no space character before the equal sign.
So wrong is
set /p %player% =
set /p %namechoice% =
because those two lines are expanded during preprocessing phase before really executing the command SET to
set /p =
set /p =
in case of environment variables player and namechoice are not already defined. See Why is no string output with 'echo %var%' after using 'set var = text' on command line? for details about how to define an environment variable right. It explains also why the space character left to equal sign on variable definition becomes part of the variable name which is nearly always unwanted by batch file writer.
Such simple syntax issues can be easily seen on running a batch file without #echo off at top of the batch file or with this line modified to #echo on or commented out with ::#echo off (invalid label) or rem #echo off (remark command) from within a command prompt window by entering name of the batch file with full path in double quotes instead of double clicking on the batch file.
What makes the difference?
With #echo off the command lines are not printed into the console window after preprocessing (expanding environment variables) before really executing them. This is the wanted behavior when batch file development finished. But during development and testing of a batch file it is definitely better to get displayed what is really executed by Windows command interpreter to find coding mistakes.
On double clicking a batch file cmd.exe is started to execute the batch file with option /C for closing the console window automatically when batch file execution terminated independent on success or error of execution. This makes it not possible to see for example syntax errors output by Windows command interpreter which result in an immediate exit of batch file execution. Therefore it is advisable during batch file development to run it from within a manually opened command prompt window as in this case cmd.exe is started with option /K to keep the console window open even after batch processing finished, except the batch file uses command exit without parameter /B. This makes it possible to see also the error message of an error which caused an unexpected exit of batch processing.
Later when batch file works as expected, the first line can be #echo off again and of course the batch file can be started with a double click. But during batch file development it is definitely better to always run the batch file from within a command prompt window. The up/down arrow keys can be used to scroll through the list of entered strings which makes it also possible to re-enter for example the player name easily again.
Here is the batch code rewritten with several improvements and comments:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
rem Define a too long player name before prompting the user for the player
rem name. This too long player name is kept in case of user hits just the
rem key RETURN or ENTER without entering anything at all. Then test for
rem entered name has not more than 6 characters. Delayed expansion is used
rem as the user could enter characters like " ! % ... which would in further
rem batch code execution result in exiting batch processing because of syntax
rem error or in unexpected behavior on referencing player name with expansion
rem before running the command.
:PromptForName
cls
echo Now that we've got your color figured out, what about your name?
echo Simply type the name you want for your character into the space
echo below (6 char max).
echo/
set "Player=No name entered"
set /P "Player=Player name: "
if not "!Player:~6!" == "" goto PromptForName
echo/
echo/
echo 1) yes
echo 2) no
echo/
choice /C:12 /N "So you want your name to be !player!? "
if errorlevel 2 goto PromptForName
if /I "!player!" == "%USERNAME%" goto GameStart
echo Surprise
endlocal
goto :EOF
:GameStart
echo/
echo Okay !Player!, let's play^^!
rem Wait 3 seconds using PING instead of TIMEOUT before exiting the
rem batch file because the command TIMEOUT does not exist on Windows XP.
%SystemRoot%\System32\ping.exe 127.0.0.1 -n 4 >nul
endlocal
The comment at top explains why the environment variable Player is defined with value No name entered. The batch user has the freedom to hit just RETURN or ENTER without entering anything at all or hits by mistake one of those 2 keys before entering a name. In this case the environment variable Player is either still not defined if not defined before, or it keeps its current value if already defined before. It is not good if the user enters nothing and the environment variable Player is not defined in this case. Therefore the player name is predefined with an invalid name.
The length of the entered player name is also tested on being too long.
And the string entered by the user could contain batch syntax critical characters like a double quote, a percent sign, a redirection operator character (angle bracket, pipe), an ampersand, or with delayed expansion enabled an exclamation mark. To prevent an exit of batch processing caused by a syntax error by entered player name on using environment variable expansion before command line execution, the environment variable Player is referenced everywhere with usage of delayed expansion enabled at top of the batch file.
For printing a blank line it is better to use echo/ instead of echo. because echo. could fail and is a little bit slower because of Windows command interpreter searches for a file matching the pattern echo.* as documented in DosTips forum article ECHO. FAILS to give text or blank line - Instead use ECHO/.
The command CHOICE is much better than set /P VariableName=Prompt text if the user has to enter specific keys. The command CHOICE does not allow that the user enters something not wanted by batch file writer and is therefore much safer for a choice menu.
The account name of current user referenced with %USERNAME% could contain also a space character. Therefore it is highly recommended to enclose the entire string containing %USERNAME% always in double quotes.
"%USERNAME%" on right side of a string comparison requires that the string on left side is also enclosed in double quotes because command IF compares the two strings with including the double quotes.
For that reason the condition
if /I !player! == "%USERNAME%"
would be only true if the batch file user would have entered the player name with double quotes which is very unlikely. The double quotes must be also used on left side.
The number of space characters around the two compared strings enclosed in double quotes or not enclosed in double quotes does not matter.
Executing in a command prompt window the following batch file
#echo on
#setlocal EnableExtensions EnableDelayedExpansion
#set "Player=<|>"
if /I "!Player!"=="%SystemRoot%" echo Strings are equal.
if /I "!Player!" == "%WinDir%" echo Strings are equal.
if /I "!Player!" == "%Player%" echo Strings are equal.
if /I "!Player!"== "!Player!" echo Strings are equal.
if /I !Player! == !Player! echo Strings are equal.
#endlocal
results in the output
if /I "!Player!" == "C:\WINDOWS" echo Strings are equal.
if /I "!Player!" == "C:\WINDOWS" echo Strings are equal.
if /I "!Player!" == "<|>" echo Strings are equal.
Strings are equal.
if /I "!Player!" == "!Player!" echo Strings are equal.
Strings are equal.
if /I !Player! == !Player! echo Strings are equal.
Strings are equal.
It can be seen that the space characters around comparison operator == do not matter on execution of command IF. The Windows command processor formats the command lines pretty before executing the IF commands.
But a space character in a string to compare requires the usage of double quotes because otherwise an exit of batch processing occurs most likely because of a syntax error on batch file execution.
Note: The equal operator == of command IF is handled different than the assignment operator = of command SET. Don't mix them.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
choice /?
cls /?
echo /?
endlocal /?
goto /?
if /?
ping /?
rem /?
set /?
setlocal /?
And see also the Microsoft article Using command redirection operators for an explanation of >nul.
How do I call multiple batch files within a single batch? When I try it always goes to the same one or none at all and closes window.
#echo off
:MENU
title MENU0
Echo 1 - Select Menu 1
Echo 2 - Select Menu 2
Echo 0 - Exit
Echo.
SET /P choice=Type the number or letter of task you want, then press ENTER:
IF %choice%==1 GOTO 1
IF %choice%==2 GOTO 2
IF %choice%==0 EXIT
:1
call %userprofile%\desktop\\Menu1.bat
:2
call %userprofile%\desktop\Menu2.bat
There are several issues with provided batch code in question.
The first one is that after processing of the batch file called with command CALL finished, the processing of current batch file continues with the next command respectively line, except the called batch file contains itself the command EXIT without parameter /B as in this case the command processor terminates itself independent on calling hierarchy.
For details about CALL behavior see answers on:
How to call a batch file in the parent folder of current batch file?
In a Windows batch file, can you chain-execute something that is not another batch file?
The second issue is that folder path assigned to environment variable USERPROFILE could contain 1 or more spaces (default on Windows 2000/XP, possible on later Windows versions depending on user name). Therefore always enclose a string referencing USERPROFILE or USERNAME in double quotes.
The third and most difficult to handle issue is that the user of a batch file on prompt with set /P has the freedom to enter anything and not just what the writer of the batch file suggests.
For example
SET /P choice=Type the number or letter of task you want, then press ENTER:
IF %choice%==1 GOTO 1
results in an exit of batch processing caused by a syntax error if the batch user hits just RETURN or ENTER without entering anything at all and the environment variable choice is not already defined with a useful string because in this case the next line to process by command processor is:
IF ==1 GOTO 1
It is good practice to define the environment variable with a default value before set /P as this value is kept when the batch user just hits RETURN or ENTER.
A batch user has also the freedom on using set /P to enter anything including syntax critical characters like " or < or | or > and others by mistake or intentionally (for breaking batch processing by a syntax error).
Therefore it is in general better for menus in batch files to use the command choice (Microsoft article) because then the batch user can enter only what the writer of the batch file offers. But CHOICE is available only by default for Windows Server 2003 and later Windows. And there are different versions of choice (SS64 article with additional information) with a different set of options. So it depends on which Windows version(s) the batch file is designed for if CHOICE can be used at all.
It is also not good to name an environment variable or a label like a command although possible. Therefore choice is not a good name for an environment variable.
Here is a commented batch file with a code which avoids all those issues.
#echo off
:MainMenu
setlocal EnableDelayedExpansion
title MENU0
cls
echo 1 - Select Menu 1
echo 2 - Select Menu 2
echo 0 - Exit
echo.
rem Define 0 as default value in case of user just hits RETURN or ENTER.
set "UsersChoice=0"
set /P "UsersChoice=Type the number or letter of task you want, then press ENTER: "
rem Has the user really entered just one of the offered characters?
rem There must be nothing to process if the user has entered just 0
rem or 1 or 2. Otherwise the user's choice was either by mistake or
rem intentionally entered wrong. The string entered by the user is
rem referenced with delayed expansion to avoid an exit of batch
rem processing in case of user entered a syntax critical character.
for /F "tokens=1 delims=012" %%I in ("!UsersChoice!") do (
endlocal
goto MainMenu
)
rem Now it is safe to reference the variable value without usage of delayed
rem expansion as a syntax error caused by user input can't occur anymore.
rem The entered string does not contain any not expected character. But
rem it is possible that for example 11 was entered by mistake instead
rem of just 1. The entered string should have a length of 1 character.
if not "%UsersChoice:~1,1%" == "" (
endlocal
goto MainMenu
)
rem Exit this batch processing on user entered 0. Previous environment is
rem automatically restored by command processor by an implicit endlocal.
if "%UsersChoice%" == "0" exit /B
rem Restore previous environment as the called batch files are most
rem likely written for using standard command environment with delayed
rem expansion not enabled (exclamation mark interpreted different).
rem The current value of local environment variable must be passed
rem to previous environment for usage on GOTO command.
endlocal & goto Menu%UsersChoice%
:Menu1
call "%USERPROFILE%\Desktop\Menu1.bat"
goto MainMenu
:Menu2
call "%USERPROFILE%\Desktop\Menu2.bat"
goto MainMenu
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
cls /?
echo /?
endlocal /?
exit /?
for /?
goto /?
rem /?
set /?
setlocal /?
title /?
For meaning of & in line endlocal & goto Menu%UsersChoice% see answer on Single line with multiple commands using Windows batch file.
I tried your code and what I found was that when the input was 1 both :1 and :2 are executed but when the input is 2 only :2 is executed. To fix this you need to specify the end of :1 using Exit or another goto.
You might see that none the batches are being executed IF you do not put a pause in the end of your script. They would be executed but the result might just flash out of the screen.
Also I do not understand why have you used \\Menu1.batand not \Menu1.bat in
:1
call %userprofile%\desktop\\Menu1.bat
The final working code for me-
#echo off
:MENU
title MENU0
Echo 1 - Select Menu 1
Echo 2 - Select Menu 2
Echo 0 - Exit
Echo.
SET /P choice=Type the number or letter of task you want, then press ENTER:
IF %choice%==1 GOTO 1
IF %choice%==2 GOTO 2
IF %choice%==0 EXIT
:1
call yourpathhere\Menu1.bat
pause
GOTO cont
:2
call whatsoever\Menu2.bat
pause
GOTO cont
:cont
exit
That should fix your problem.
Hope I helped.
I may not be a pro, but I could help you!
I always add extra code on my games in order to avoid bugs, like this:
set /p letter=
if %letter% == 1 goto nocheck1
if %letter% == 2 goto nocheck2
if %letter% == 3 exit
:nocheck1
if %letter% == 1 goto saves
:nocheck2
if %letter% == 2 goto howtoplay
Maybe it could work on your problem!
I might have the code to do it:
#echo off
cls
:menu
cls
echo 1. Open Batch 1
echo 2. Open Batch 2
set /p test=Enter number here ----->
if %test% == 1 goto check1
if %test% == 2 goto check2
Edit the "Batch file name" text with your location of your batch file.
:check1
if %test% == 1 start C:\Users\%username%\Desktop\(batch file name).bat
:check2
if %test% == 2 start C:\Users\%username%\Desktop\(batch file name).bat
If there's still any errors with my code, let me know.
Hope this helps your problem!
Use cd to go to the location of batch file. For example:
rem myscript
echo calling batch file
cd demo\desktop\script
execute.bat
echo done
After the execution of that batch, control will return to the next line of your script.
Use "Start" instead of "Call" like so,
#echo off
:MENU
title MENU0
Echo 1 - Select Menu 1
Echo 2 - Select Menu 2
Echo 0 - Exit
Echo.
SET /P choice=Type the number or letter of task you want, then press ENTER:
IF %choice%==1 GOTO 1
IF %choice%==2 GOTO 2
IF %choice%==0 EXIT
:1
start %userprofile%\desktop\\Menu1.bat
:2
start %userprofile%\desktop\Menu2.bat
Try This:
#echo off
:MENU
title MENU0
Echo 1 - Select Menu 1
Echo 2 - Select Menu 2
Echo 0 - Exit
Echo.
SET /P choice=Type the number or letter of task you want, then press
Enter:
IF %choice%==1 GOTO 1
IF %choice%==2 GOTO 2
IF %choice%==0 EXIT
:1
cd users
cd %userprofile%
cd desktop
:: call Menu1.bat or use: start Menu1.bat
:: exit
:2
cd users
cd %userprofile%
cd desktop
:: call Menu2.bat or use: start Menu2.bat
:: exit
start "" C:\location\of\file\file.bat
This opens a new window, and as long as you have more commands to follow, the previous file that is calling the new one will still run along with this one.
I am new to writing batch files. I want to create a batch file that will allow me to change 2 directories using variables. What I have below is what I have thus far. Any ideas?
#echo off
S:
cd AAA
set /p CLIENTCODE=CLIENTCODE?
cd %CLIENTCODE%
pause
set /p SCHEMANAME=SCHEMANAME?
cd %SCHEMANAME%
pause
Try following batch code:
#echo off
setlocal
set "ClientCode=AAA"
set "SchemaName=5H"
:UserPrompt
cls
set /P "ClientCode=Enter client code (default: %ClientCode%): "
set /P "SchemaName=Enter schema name (default: %SchemaName%): "
if not exist "S:\%ClientCode%\%ClientCode%%SchemaName%" goto InputError
cd /D "S:\%ClientCode%\%ClientCode%%SchemaName%"
endlocal
goto :EOF
:InputError
echo.
echo Client code "%ClientCode%" or schema name "%SchemaName%" is not valid.
set "InputAgain=Y"
set /P "InputAgain=Enter data again (Y/N)? "
if /I "%InputAgain%" == "Y" goto UserPrompt
if /I "%InputAgain%" == "YES" goto UserPrompt
endlocal
This batch file first defines defaults for client code and schema name making it possible for the user to simply hit key RETURN or ENTER when defaults are okay.
Next the window is cleared and the user is prompted for client code and schema name. The input of the user is not validated at all.
A very simple check is made if the appropriate directory (or file) exists.
The current directory is changed if a directory according to entered data exists.
If the directory does not exist, the user is asked if data input should be repeated in case of a typing mistake. The user can input Y or YES in any case to redo data input. Otherwise the batch script exits without changing the directory.
There is no real effort made on validating user input strings and verifying if the entered strings really lead to a directory and not a file.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
cls /?
echo /?
endlocal /?
goto /?
if /?
set /?
setlocal /?