Password system does not work - batch-file

Here is the code I am trying to solve:
set /p password= Password (Put in Guest if guest login):
if %password% == %pass% goto desktop
if not %password% == %pass% goto bootscreentwo
if %password% == Guest goto ltddesktop
:desktop
it is for a "Mini operating system" made in batch.

The code does not work if the user just hits RETURN or ENTER resulting in environment variable password still not being defined as not defined with an initial value above line with set /p.
This results on IF condition with immediate expansion of environment variable password and with pass having value xxx in the command line:
if == xxx goto desktop
The left string is missing and therefore batch execution is exited because of a syntax error as it can be seen on running the batch file without #echo off at top of the batch file from within a command prompt window instead of double clicking on the batch file.
Also if the entered string contains for example | or & or < or > the immediate expansion of environment variable password result on parsing the IF condition line in a syntax error with an immediate exit of batch file execution.
The common solution to get characters with special meaning interpreted as literal characters is putting both strings to compare in double quotes. The double quotes are also compared by IF and not just the string between the double quotes. Therefore it is necessary to double quote both strings.
if "%password%" == "%pass%" goto desktop
if not "%password%" == "%pass%" goto bootscreentwo
if "%password%" == "Guest" goto ltddesktop
Which characters require double quotes around a string is explained in help of Windows command interpreter output by running in a command prompt window cmd /? in last paragraph on last output help page. The redirection operators >, < and | are missing in this list as those characters can't be used in file names.
But there is still a problem even on using double quotes around the strings to compare if the batch file user enters a string containing 1 or more double quotes as this results with immediate environment variable expansion again in a syntax error on execution of IF command line.
The solution is using delayed environment variable expansion as explained by help of command SET output on running in a command prompt window set /?.
First suggestion for the batch code on where the user has to enter guest for using guest access:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "pass=xxx"
:EnterPassword
set "password="
set /P "password=Enter "Guest" for guest login. Password: "
if "!password!" == "" goto EnterPassword
rem Case-sensitive password string compare using delayed expansion.
if "!password!" == "!pass!" goto desktop
rem Case-insensitive password string compare using delayed expansion.
if /I "!password!" == "Guest" goto ltddesktop
echo bootscreentwo
goto :EOF
:desktop
echo Label desktop
goto :EOF
:ltddesktop
echo Label ltddesktop
goto :EOF
Windows command interpreter does implicitly do an endlocal on exiting batch file execution on executing goto :EOF resulting in restoring previous command process environment.
Second suggestion for batch code with guest being default password:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "pass=xxx"
:EnterPassword
set "password=guest"
set /P "password=Press ENTER for guest login. Password: "
rem Case-insensitive password string compare using delayed expansion.
if /I "!password!" == "Guest" goto ltddesktop
rem Case-sensitive password string compare using delayed expansion.
if "!password!" == "!pass!" goto desktop
echo bootscreentwo
goto :EOF
:desktop
echo Label desktop
goto :EOF
:ltddesktop
echo Label ltddesktop
goto :EOF
Please note that enabled delayed expansion results in interpreting ! anywhere in batch code as beginning of an environment variable reference. So be careful on using ! for example in an ECHO line as the exclamation mark must be escaped to be interpreted as literal character. It would be best to use endlocal before further processing the batch file if the values of password and pass are no longer needed after this batch code block.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "pass=xxx"
:EnterPassword
set "password=guest"
set /P "password=Press ENTER for guest login. Password: "
rem Case-insensitive password string compare using delayed expansion.
if /I "!password!" == "Guest" endlocal & goto ltddesktop
rem Case-sensitive password string compare using delayed expansion.
if "!password!" == "!pass!" endlocal & goto desktop
endlocal
echo bootscreentwo with pass and password not defined anymore.
goto :EOF
:desktop
echo Label desktop with pass and password not defined anymore.
goto :EOF
:ltddesktop
echo Label ltddesktop with pass and password not defined anymore.
goto :EOF
pass and password are not defined anymore after the string compares, except those two environment variables existed already before execution of SETLOCAL command in second line in which case their original values are restored by ENDLOCAL. See this answer for details about the commands SETLOCAL and ENDLOCAL.
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.
echo /?
endlocal /?
goto /?
if /?
rem /?
set /?
setlocal /?

Related

How to save a variable to a batch file?

This is my code:
set /p name=user save name
if %name%==[""]
cd c:\users\student\desktop\login system\usersXD
echo set "name=%name%"> %name%.bat
My code is not working. and i will like to load them up to view
I suggest following code for this task:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
goto PromptName
:ErrorInvalid
echo/
echo Error: The character !InvalidChar! is not allowed in name.
echo/
endlocal
:PromptName
set "Name="
set /P "Name=User save name: "
rem Has the user not input anything?
if not defined Name goto PromptName
rem Remove all double quotes from input string.
set "Name=%Name:"=%"
rem Has the user input just double quotes?
if not defined Name goto PromptName
rem Check if the input string contains any character not allowed in a file name.
setlocal EnableDelayedExpansion
for %%I in ("<" ">" ":" "/" "\" "|") do if not "!Name:%%~I=!" == "!Name!" set "InvalidChar=%%~I" & goto ErrorInvalid
if not "!Name:?=!" == "!Name!" set "InvalidChar=?" & goto ErrorInvalid
if not "!Name:**=!" == "!Name!" set "InvalidChar=*" & goto ErrorInvalid
endlocal
cd /D "%UserProfile%\Desktop\login system\usersXD"
echo set "Name=%Name%">"%Name%.bat"
endlocal
The file name of the batch file to create must be enclosed in double quotes because it could contain a space or one of these characters &()[]{}^=;!'+,`~ which require enclosing the file name in double quotes.
This batch file should not be stored in directory %UserProfile%\Desktop\login system\usersXD on having file extension .bat as it could be overwritten during execution if the user enters a name the name of the batch file. It would be safe to have this batch file in that directory with file extension .cmd.
The batch file is still not 100% fail-safe despite the checks already added, but the user input string itself cannot result anymore in an exit of batch file execution because of a syntax error.
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 /?
echo /?
endlocal /?
for /?
goto /?
if /?
rem /?
set /?
setlocal /?
See also:
Wikipedia article listing the predefined Windows environment variables like UserProfile
Single line with multiple commands using Windows batch file explaining the operator &
How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
Microsoft documentation page Using command redirection operators explaining the redirection operator >
Microsoft documentation page Naming Files, Paths, and Namespaces listing which characters are not allowed in file/folder names
This should work to save a variable in a bat file
If I remember
(
Echo set test=%
Echo set test=%test%
Echo set test=%test%
)>Test.bat

How to show what user typed in this command?

please help! I was looking for the answer all over the internet.
Here's my code:
#echo off
title var test
:question
set a1=This
set a2=Is
set a3=a
set a4=Var
set a5=Test
choice /c 12345 /m "press a number"
if errorlevel=5 set num=5&goto answer
if errorlevel=4 set num=4&goto answer
if errorlevel=3 set num=3&goto answer
if errorlevel=2 set num=2&goto answer
if errorlevel=1 set num=1&goto answer
:answer
echo now change the answer.
set /p a%num%=
FOR /F "tokens=1-6" %%1 IN ("%a1% %a2% %a3% %a4% %a5% a%num%") DO echo %%1 %%2 %%4 %%5.&echo You typed=%%6
pause
goto question
As you can see I made the user select a number between 1 and 5 to change the specific word. But when I try same kind of code to show what he typed doesn't work :(
Environment variables should never begin with a digit and using a digits for loop variables should be also avoided. Run in a command prompt window call /? and output is the help for this command explaining how batch file arguments can be referenced with %0, %1, %2, ... which explains why environment variables with digit as first character and loop variables with a digit are not good in general even on being
a%num% in set of FOR does not reference the value of environment variable a1 or a2 or a3 or a4 or a5. It is just the name of the environment variable. The for loop is not necessary at all.
#echo off
title var test
:question
set "a1=This"
set "a2=Is"
set "a3=a"
set "a4=Var"
set "a5=Test"
%SystemRoot%\System32\choice.exe /C 12345E /N /M "Press a number in range 1-5 or E for exit: "
if errorlevel 6 goto :EOF
set "num=%ERRORLEVEL%"
set /P "a%num%=Now change the answer: "
echo %a1% %a2% %a3% %a4% %a5%.
call echo You typed: %%a%num%%%
pause
goto question
The command line call echo You typed: %%a%num%%% is parsed by Windows command processor before execution of the command line on number 3 entered to call echo You typed: %a3%. This command line is parsed a second time because of command call resulting in replacing %a3% by the value of environment variable a3 and so echo outputs the expected string.
It would be also possible to replace call echo You typed: %%a%num%%% by
setlocal EnableDelayedExpansion
echo You typed: !a%num%!
endlocal
The usage of delayed environment variable expansion results also in double parsing the command line before execution of command echo. For more details see How does the Windows Command Interpreter (CMD.EXE) parse scripts?
Please read also this answer for details about the commands SETLOCAL and ENDLOCAL.
The two lines below in batch code above are also not really good taking into account that the user can really enter anything.
echo %a1% %a2% %a3% %a4% %a5%.
call echo You typed: %%a%num%%%
For example if the user enters number 1 and on next prompt enters:
Your user name is:& setlocal EnableDelayedExpansion & echo !UserName!& endlocal & rem
Then the batch file does something completely different than designed for and outputs the user's account name.
Secure would be the batch code:
#echo off
title var test
setlocal EnableExtensions DisableDelayedExpansion
:question
set "a1=This"
set "a2=Is"
set "a3=a"
set "a4=Var"
set "a5=Test"
%SystemRoot%\System32\choice.exe /C 12345E /N /M "Press a number in range 1-5 or E for exit: "
if errorlevel 6 goto :EOF
set "num=%ERRORLEVEL%"
set /P "a%num%=Now change the answer: "
setlocal EnableDelayedExpansion
echo !a1! !a2! !a3! !a4! !a5!.
echo You typed: !a%num%!
endlocal
pause
goto question
Now the user input string cannot modify anymore the command lines executed by Windows command processor.
A solution with the useless FOR loop would be:
setlocal EnableDelayedExpansion
for /F tokens^=1-6^ eol^= %%A in ("!a1! !a2! !a3! !a4! !a5! !a%num%!") do echo %%A %%B %%C %%D %%E.&echo You typed: %%F
endlocal
eol= is necessary to output everything correct also if use enters number 1 and next a string starting with a semicolon. The FOR options string cannot be enclosed in double quotes in this case like "tokens=1-6 eol=" because of this would define " as end of line character and nothing is output if user enters number 1 and enters next a string starting with ". The equal sign and the space must be escaped with ^ to be interpreted as literal characters by cmd.exe on double parsing the entire for command line before execution of command for.
Note: The FOR loop solution does not work correct on user enters for first variable value the special command line string as posted above. So it is also not really secure.

insert a variable into a variable in batch

I'm trying to insert a variable into a variable, I've tried this, but it didn't work:
set gabriel-ctCODE=fmfg1
set /p user=Username:
set /p password=Password:
set /p ctCODE=ctCODE:
if %password%== %%user%-pass% set /a loginerrorlevel=%loginerrorlevel%+1
pause
if %ctCODE%== "%%user%-ctCODE%" set /a loginerrorlevel=%loginerrorlevel%+1
if not %loginerrorlevel%== 2 goto login.incorrect
goto :aftercommand
I would like to insert the "user" variable into this variable: %%user%-pass%
Could you help me please?
Here is your batch code rewritten for validating entered credential data:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "gabriel-ctCODE=fmfg1"
set "gabriel-pass=xxxyyy"
set "UserName="
set /P "UserName=User name: "
set "Password="
set /P "Password=Password: "
set "ctCODE="
set /P "ctCODE=ctCODE: "
call set "UserPass=%%%UserName%-pass%%"
call set "UserCode=%%%UserName%-ctCODE%%"
set "LoginErrorLevel=0"
if "!Password!" == "!UserPass!" set /A LoginErrorLevel+=1
if "!ctCODE!" == "!UserCode!" set /A LoginErrorLevel+=1
if not %LoginErrorLevel% == 2 goto LoginIncorrect
echo Entered credential data are valid for login.
goto EndBatch
:LoginIncorrect
echo Enter credential data not valid for login.
:EndBatch
endlocal
On set /P the user of the batch file has the freedom to enter nothing in which case the environment variable keeps its current value or is still not defined if not defined before. The batch code above makes sure that the 3 environment variables are not defined before prompting the user.
The batch file user has also the freedom to enter anything including critical characters for batch file execution like %, > <, ", etc. which is the reason for enclosing the variable=value assignments in double quotes as this results in interpreting the entered characters as literal characters and using delayed expansion on string comparisons.
Read the answers on Why is no string output with 'echo %var%' after using 'set var = text' on command line? and on Password system does not work for more details.
To get the values of the environment variables gabriel-ctCODE and gabriel-pass when the user enters gabriel (in any case) as user name, the command SET must be used with appropriate string and additionally the command CALL to expand the environment variable inside the variable string. Read for example answer on Pass environment variables to subshell CMD for details.
An arithmetic expression is everything after set /A which is interpreted by Windows command line interpreter completely different than usual.
For details on behavior of the commands SETLOCAL and ENDLOCAL read this answer.
For a basic understanding of 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 /?
echo /?
endlocal /?
goto /?
if /?
set /?
setlocal /?

.Bat code only creates file for one set of data entered

I want to create a bat file asking for a user input which will ask for some choices:
#echo off
MKDIR D:\BatFiles\File
SET /P Output="D:\BatFiles\File"
ECHO Select Task
ECHO ==========
#echo off
title Task List Creator
:homescreen
ECHO
Echo 1.) Create Notepad Task File
Echo 2.) Exit
Echo.
set /p input=Type Choice :
if "%input%"=="1" goto getInfo
if "%input%"=="2" exit
Pause
:getInfo
set /p VarOne=Enter Type:
set /p VarTwo=Enter Number:
set /p VarThree=Enter Name:
echo Task Type=%VarOne% >> %Output%\test.txt
echo Task Number=%VarTwo% >> %Output%\test.txt
echo Task Name=%VarThree% >> %Output%\test.txt
echo Entry successfully written
Pause
goto finished
:finished
echo Do you want to create a new set of entry?
set /p response= Y or N?
if "%response%"=="Y" goto getInfo
if "%response%"=="N" goto homescreen
--The problem with this code is that I want to create more than 2 entries. This code only creates an output file if user has only one set of entries. If user creates 2 or more, the output file is not created and data entered appears only when user runs the bat file again and only enters one set of data. Sorry about the lame question, I'm just a batch file beginner here.
Look on this code:
#echo off
title Task List Creator
setlocal EnableExtensions EnableDelayedExpansion
set "OutputFolder=D:\BatFiles\File"
set FileNumber=0
:HomeScreen
cls
echo Select Task
echo ===========
echo.
echo 1 ... Create Notepad Task File
echo 2 ... Exit
echo.
set "Input=2"
set /P "Input=Your choice: "
if "!Input!"=="1" goto PrepareTaskFile
if "!Input!"=="2" endlocal & goto :EOF
goto HomeScreen
:PrepareTaskFile
set /A FileNumber+=1
set "OutputFile=%OutputFolder%\test%FileNumber%.txt"
if exist "%OutputFile%" del "%OutputFile%"
:GetInfo
echo.
set "VarOne="
set "VarTwo="
set "VarThree="
:EnterType
set /P "VarOne=Enter type: "
if not defined VarOne goto EnterType
:EnterNumber
set /P "VarTwo=Enter number: "
if not defined VarTwo goto EnterNumber
:EnterName
set /P "VarThree=Enter name: "
if not defined VarThree goto EnterName
if not exist "%OutputFolder%" mkdir "%OutputFolder%"
echo Task Type=!VarOne!>>"%OutputFile%"
echo Task Number=!VarTwo!>>"%OutputFile%"
echo Task Name=!VarThree!>>"%OutputFile%"
echo.
echo Entry successfully written.
echo.
pause
echo.
echo Do you want to create a new set of entry?
echo.
set "Response=N"
set /P "Response=Y or N? "
if /I "!Response!"=="Y" goto GetInfo
goto HomeScreen
The environment variable on prompt keeps its current value if the user just hits RETURN or ENTER. Therefore it is advisable to define a default value or undefine a variable before prompting the user.
The entered strings assigned to the variables are referenced with usage of delayed expansion in case of user enters something not expected which could result in a syntax error and therefore exit of batch processing on referencing the entered strings with immediate expansion. For example a string comparison would fail with a syntax error if the user enters a string with a double quote.
See How to set environment variables with spaces? why using double quotes as it can be seen here on set "variable=string value" and set /P "variable=prompt text".
The space character left of redirection operator >> in code of question would be also written into the file. This should be avoided by removing it and reference the variables with delayed expansion in case of the variable value is a number with value 1, 2, 3, ... to avoid a wrong handle redirection, see the Microsoft article about Using command redirection operators.
On usage of set /P for a menu instead of command choice it must be always taken into account that the user enters something not suggested. So if the user enters on first prompt whether 1 nor 2, there must be code which defines the behavior on the invalid input.
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 /?
del /?
echo /?
endlocal /?
goto /?
if /?
mkdir /?
pause /?
set /?
setlocal /?
title /?
See also answer on Single line with multiple commands using Windows batch file for an explanation of & between endlocal and goto :EOF.

Windows script doesn't work when user types in a whitespace

I'm writing a Windows script in batch. I have a problem with whitespaces in variables. When the user types in a space, the script breaks.
Here's the part of my script:
:package
SET /P packageName="Set package name:"
IF [%packageName%] EQU [] (
ECHO Empty package name.
goto package
) ELSE (
set "packageName=%packageName: =%"
echo %packageName%
pause
)
This schould work:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
:package
SET /P packageName="Set package name:"
IF "%packageName%"=="" (
ECHO Empty package name.
goto package
) ELSE (
set packageName=%packageName: =%
echo !packageName!
pause
)
There are two modifications to your script:
[%packageName%] EQU [] was replaced with "%packageName%"==""
I've added SETLOCAL ENABLEDELAYEDEXPANSION and changes echo %packageName% with echo !packageName!
The second point is because you are changing the value of a variable inside an IF-construction. As the interpreter doesn't know what the new value will be at "compile" time, you have to evaluate the variable at run time. That's why you need SETLOCAL ENABLEDELAYEDEXPANSION and !...! instead of %...%. This forces the expansion at run time.
I suggest to use this code:
#echo off
setlocal EnableDelayedExpansion
:package
rem Predefine variable packageName with a single double quote as value.
rem This value is kept if the user just hits RETURN or ENTER on prompt.
rem The single double quote is removed 2 command lines below if the user
rem does not enter anything or it is overwritten by user entered string.
set "packageName=""
set /P "packageName=Set package name: "
rem Remove double quotes from entered string. This is necessary to
rem avoid a syntax error on next command line with the IF condition.
set "packageName=!packageName:"=!"
if "!packageName!" == "" (
echo Empty package name.
goto package
) else (
set "packageName=%packageName: =%"
echo Package name with spaces: %packageName%
echo Package name without spaces: !packageName!
pause
)
endlocal
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.
if /?
set /?
setlocal /?
Especially the help pages output on execution of if /? should be read carefully and completely as this helps explains delayed expansion as it must be used here on examples.
See also the output of the 2 echo lines in ELSE branch in code above to understand what is the difference between referencing a variable with percent signs or with exclamation marks in blocks defined with ( ... ).
Your script is almost correct except for "variable search/replace" which its position is to be before "IF"
#echo off
:package
set /p packagename="set package name:"
set packagename=%packagename: =%
if [%packagename%] equ [] (
echo empty package name &goto package
) else (echo %packagename%)

Resources