I wrote recently a folder locking program.
My only problem is that when I need to change the password, e.g. I go to section newpass
, the program doesn\'t se
At the end is your batch code rewritten to avoid the need of delayed environment variable expansion because of setting an environment variable within an IF
block and evaluating it in same block as you did in
if %oldpass%==%password% (
attrib -h -s "password.txt"
attrib -h -s "tipp.txt"
cls
echo.
echo Enter new password.
set/p newpass= ">"
echo( %newpass% > password.txt
)
rem ...
)
Command line interpreter cmd.exe
replaces all %env%
within (
... )
block by their values before evaluating the IF
condition resulting for example in newpass
always being nothing (most likely). Read in a command prompt window the entire help on command set
output after entering either help set
or set /?
for details about delayed expansion.
There is {
instead of (
in the above code block in your question.
You should indent lines within a (
... )
block as otherwise it is hard for anybody to see the block structure which makes code checking very difficult.
If a user has to enter a string assigned to an environment variable, the user can always hit just key RETURN or ENTER without entering anything. In this case the value of the environment variable is not changed at all if the environment variable already existed. Therefore it is advisable to make sure that the environment variable does not exist before using set /p
if the user must enter something.
The other possibility is that a default value is assigned to the environment variable so that a user needs to press only RETURN or ENTER if the default value should be used. But in this batch code the user should always enter all strings.
It is possible to assign a string with spaces to an environment variable and the spaces can be also at end of the strings. Trailing spaces in a batch file is a common reason for a batch file not working as expected. The solution is using set "var=value" as in this case the trailing spaces after the second double quote are ignored on command execution.
Comparison of an environment variable with a string value should be done always on using double quotes around environment variable reference and the string value. Otherwise it can happen easily with user entering nothing that the IF
condition is parsed as
if ==new goto newpass
which is invalid and cmd.exe
breaks execution of the batch file. This can't happen anymore with
if /i "%pass%"=="new" goto NEWPASS
/i
makes the compare case-insensitive.
But the user can nevertheless break execution of batch file by entering now a double quote character. The solution is to remove all double quotes from entered string before making the string comparison as for example done with
set newpass=%newpass:"=%
But this results in one more problem if newpass
is removed before user is prompted to enter new password and the user enters nothing. This would result again in an invalid command line syntax for cmd.exe
. The solution is to predefine newpass
and passtipp
with just "
as value. Now the user can hit key RETURN, but the variables would nevertheless exist with "
as value. This double quote is removed next and batch code detects on next line that the user has not entered anything as otherwise the single double quote would have been replaced by something different.
@echo off
title Folder Locker by KBKOZLEV
:SETPASS
set "tipp="
set "password="
if exist "password.txt" (
set /p password= nul
exit
:MDLOCKER
md "Unlocked"
echo>password.txt 1234
echo>tipp.txt 1234
attrib +h +s "password.txt"
attrib +h +s "tipp.txt"
cls
echo.
echo Private folder created successfully.
CHOICE /C X /T 5 /D X > nul
goto END
:OPEN
cls
echo.
echo Password tipp: %tipp%
echo.
echo Enter password to unlock folder or
echo enter "new" to set a new password.
echo.
set "pass="
set /p "pass=Password: "
if /i "%pass%"=="new" goto NEWPASS
if "%pass%"=="%password%" (
attrib -h -s "Locked"
ren "Locked" "Unlocked"
echo.
echo Folder unlocked successfully.
goto END
)
goto FAIL
:FAIL
cls
echo.
echo Invalid password, please try again.
CHOICE /C X /T 5 /D X > nul
cls
goto OPEN
:NEWPASS
cls
echo.
set "oldpass="
set /p "oldpass=Old password: "
if not "%oldpass%"=="%password%" goto FAIL
:ENTERNEW
cls
echo.
set "newpass=""
set /p "newpass=New password: "
set newpass=%newpass:"=%
if "%newpass%"=="" (
echo.
echo Invalid new password, please enter new password again.
CHOICE /C X /T 5 /D X > nul
goto ENTERNEW
)
if exist "password.txt" attrib -h -s "password.txt"
echo>password.txt %newpass%
echo.
set "passtipp=""
set /p "passtipp=New tipp: "
set passtipp=%passtipp:"=%
if exist "tipp.txt" attrib -h -s "tipp.txt"
if not "%passtipp%"=="" (
echo>tipp.txt %passtipp%
) else (
del "tipp.txt"
)
goto SETPASS
:END
Everything written here was already written thousands of times in Stack Overflow answers on questions with tag batch-file. It would have been good reading 20 to 30 answers here before starting batch code development.
Edit on 2015-05-08:
Here is an even better version than above in case of a user of this batch file enters <
or >
in password or as tip. It uses delayed expansion where necessary to avoid that those 2 characters are interpreted as redirection statements.
@echo off
setlocal EnableDelayedExpansion
title Folder Locker by KBKOZLEV
:SETPASS
set "tipp="
set "password="
if exist "password.txt" (
set /p password= nul
exit
:MDLOCKER
md "Unlocked"
echo>password.txt 1234
echo>tipp.txt 1234
attrib +h +s "password.txt"
attrib +h +s "tipp.txt"
cls
echo.
echo Private folder created successfully.
CHOICE /C X /T 5 /D X > nul
goto END
:OPEN
cls
echo.
echo Password tipp: %tipp%
echo.
echo Enter password to unlock folder or
echo enter "new" to set a new password.
echo.
set "pass=""
set /p "pass=Password: "
set "pass=!pass:"=!"
if /i "%pass%"=="new" goto NEWPASS
if "%pass%"=="%password%" (
attrib -h -s "Locked"
ren "Locked" "Unlocked"
echo.
echo Folder unlocked successfully.
goto END
)
goto FAIL
:FAIL
cls
echo.
echo Invalid password, please try again.
CHOICE /C X /T 5 /D X > nul
cls
goto OPEN
:NEWPASS
cls
echo.
set "oldpass=""
set /p "oldpass=Old password: "
set "oldpass=!oldpass:"=!"
if not "%oldpass%"=="%password%" goto FAIL
:ENTERNEW
cls
echo.
set "newpass=""
set /p "newpass=New password: "
set "newpass=!newpass:"=!"
if "%newpass%"=="" (
echo.
echo Invalid new password, please enter new password again.
CHOICE /C X /T 5 /D X > nul
goto ENTERNEW
)
if exist "password.txt" attrib -h -s "password.txt"
echo>password.txt !newpass!
echo.
set "passtipp=""
set /p "passtipp=New tipp: "
set "passtipp=!passtipp:"=!"
if exist "tipp.txt" attrib -h -s "tipp.txt"
if not "%passtipp%"=="" (
echo>tipp.txt !passtipp!
) else (
del "tipp.txt"
)
goto SETPASS
:END
endlocal