以下是我要解决的代码:
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
是批量生产的“迷你操作系统”。
答案 0 :(得分:2)
如果用户只是点击 RETURN 或 ENTER ,则代码不起作用,导致环境变量password
仍未定义为未定义初始值上面有set /p
行。
这导致 IF 条件,在命令行中立即展开环境变量password
并且pass
具有值xxx
:
if == xxx goto desktop
左侧字符串丢失,因此由于语法错误而退出批处理执行,因为在命令提示符窗口中运行不带@echo off
批处理文件顶部的批处理文件时可以看到批处理执行而不是双点击批处理文件。
此外,如果输入的字符串包含例如|
或&
或<
或>
,则环境变量password
的立即扩展会导致解析< strong> IF 条件行语法错误,立即退出批处理文件。
将具有特殊含义的字符解释为文字字符的常见解决方案是将两个字符串用双引号进行比较。双引号也通过 IF 进行比较,而不仅仅是双引号之间的字符串。因此,有必要对两个字符串进行双重引用。
if "%password%" == "%pass%" goto desktop
if not "%password%" == "%pass%" goto bootscreentwo
if "%password%" == "Guest" goto ltddesktop
在Windows命令解释器输出的帮助下,通过在最后一个输出帮助页面的最后一段中的命令提示符窗口cmd /?
中运行,解释了哪些字符需要字符串周围的双引号。此列表中缺少redirection operators >
,<
和|
,因为这些字符无法在文件名中使用。
但即使在字符串周围使用双引号来比较批处理文件用户是否输入包含1个或更多双引号的字符串仍然存在问题,因为这会导致在执行<时语法错误时立即再次扩展环境变量strong> IF 命令行。
解决方案是使用延迟环境变量扩展,如命令提示符窗口set /?
中运行命令 SET 输出所述。
关于用户必须输入guest
以使用访客权限的批次代码的第一个建议:
@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命令解释程序在执行endlocal
时执行退出批处理文件时隐式执行goto :EOF
,从而导致恢复以前的命令进程环境。
对于guest
为默认密码的批次代码的第二个建议:
@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
请注意,启用延迟扩展会导致在批处理代码中的任何位置解释!
作为环境变量引用的开头。因此,请注意在 ECHO 行中使用!
,因为必须将感叹号转义为文字字符。如果在此批处理代码块之后不再需要endlocal
和password
的值,则最好在进一步处理批处理文件之前使用pass
。
@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
和password
不再定义,除了在第二行执行 SETLOCAL 命令之前已经存在的那两个环境变量,在这种情况下它们是原始的值由 ENDLOCAL 恢复。有关命令 SETLOCAL 和 ENDLOCAL 的详细信息,请参阅this answer。
要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。
echo /?
endlocal /?
goto /?
if /?
rem /?
set /?
setlocal /?