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
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
.