这是我到目前为止所拥有的:
echo Please enter your username:
set /p choice=username:
for /f "usebackq delims=" %%i in ("files\LogCreds.data") do set "name=%%i"
if '%choice%'=='%name%' goto menu
if not '%choice%'=='%name%' goto LoginScreen
因此,LogCreds.data 文件中写入的内容都将设置为 %name%,如果用户写入相同的内容,他们就会进入菜单。
请打开命令提示符窗口并运行
choice /?
以获取 Windows 命令 choice 的使用帮助输出,该命令具有完全限定文件名 %SystemRoot%\System32\choice.exe
。虽然可以命名环境变量 choice
,但最好用以下行替换前两行:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
:PromptName
set "NameUser="
set /P "NameUser=Please enter your user name: "
rem If the user entered nothing, prompt again for user name.
if not defined NameUser goto PromptName
rem Remove all double quotes from user input string.
set "NameUser=%NameUser:"=%"
rem If the user entered just double quotes, prompt again for user name.
if not defined NameUser goto PromptName
默认定义了环境变量
USERNAME
,因为它可以在命令提示符窗口 set user
中运行时看到,以获取名称以字符串 user
开头的所有环境变量及其值。因此,用户输入字符串被分配给名称为 NameUser
而不是 UserName
的环境变量。
下一个命令行应该是:
set "NameFile="
if exist "%~dp0files\LogCreds.data" for /F usebackq^ delims^=^ eol^= %%i in ("%~dp0files\LogCreds.data") do set "NameFile=%%i"
该命令行从
LogCreds.data
引用的批处理文件目录中的子文件夹 files
中的文件 %~dp0
中读取所有非空行,该批处理文件引用驱动器和参数 0 的路径,这是始终以 a 结尾的完整批处理文件路径反斜杠。最后一个非空行被分配给环境变量NameFile
,它甚至可以以分号开头,因为使用这种特殊语法来定义无分隔符和行结束符。
字符
'
对于 Windows 命令处理器没有特殊含义,除了在 for /F
命令行中用于圆括号中的集合之外。所以这个字符的使用完全是在字符串比较上。要使用的字符是 "
,应始终在未知字符和长度的参数字符串上使用。
第一个 IF 条件应该是:
if /I "NameUser" == "%NameFile%" goto menu
此命令行进行不区分大小写的字符串比较,其中双引号包含在字符串比较中。有关更多详细信息,请参阅我对 Windows 批处理文件中相当于 NEQ、LSS、GTR 等的符号的回答,其中详细解释了使用 Windows 命令 IF 完成的字符串比较。
第二个 IF 条件根本没有必要。接下来的命令行适用于两个名称不相等的用例。
应该有额外的代码来检查
NameFile
是否已定义,即文件 %~dp0files\LogCreds.data
根本存在并且不是空文件。比如:
if not defined NameFile (
md "%~dp0files" 2>nul
if exist "%~dp0files\" (
rem The path could contain one or more exclamation marks which should
rem not be interpreted as beginning/end of a delayed expanded variable
rem reference. For that reason assign the fully qualified file name to
rem an environment variable referenced below with delayed expansion.
set "FileName=%~dp0files\LogCreds.data"
rem Delayed expansion is necessary as the variable value could contain
rem also characters like ampersand, pipe, angle brackets, etc. which
rem should be output as literal characters and do not modify the
rem ECHO command line to execute.
setlocal EnableDelayedExpansion
rem The user entered string could start with /? which should not be
rem interpreted by ECHO to output the usage help, but as string to
rem output into the file. For that reason an opening round bracket
rem is used instead of a space character as separator between the
rem command ECHO and the string to output.
echo(!NameUser!>"!FileName!"
endlocal
set "FileName="
)
)
批处理文件应以命令
endlocal
作为 Windows 命令处理器执行的最后一行结束,然后离开批处理文件的处理以恢复初始执行环境。该命令行也可以省略,因为在退出批处理文件处理之前,cmd.exe
会为每个setlocal
自动执行此命令,而无需endlocal
。
要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。
call /?
...对于%~dp0
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
rem /?
set /?
setlocal /?
另请参阅:如何阻止 Windows 命令解释器在用户输入不正确时退出批处理文件执行? 它详细解释了如何提示用户输入字符串以及如何进一步安全可靠地处理用户输入字符串以及如何使用命令 CHOICE 选择菜单。
我还建议阅读如何将批处理文件游戏的变量保存到文本文件/从文本文件加载?将变量值保存到文件中并在下次启动批处理文件时将它们读回的代码可能会容易得多将带有名称、等号和值的变量保存到数据文件中。