我有一个小程序,当我运行"如果存在"它关闭了,有人可以告诉我为什么吗?我检查了语法错误,没有(我想),我会在这里粘贴我的代码,看看你能做些什么。
echo What drive would you like to launch MCEdit on?
set /p DRIVE="Drive: "
if exist "%DRIVE%:\MC\DATA\mcedit\mcedit.exe" (
set APPDATA=%DRIVE%:\MC\DATA
start %DRIVE%:\MC\DATA\mcedit\mcedit.exe
) else (
echo You do not have MCEdit installed on this drive, would you like to install it?
set /p YesNoIn="[y/n]: "
if "%YesNoIn%"=="y" goto:yes
goto:menu
:yes
echo Choose the "mcedit.exe" file from a current installation on your pc.
pause
call "%DRIVE%\MC\DATA\FileViewer.bat"
xcopy "%OutCD%" "%DRIVE%:\MC\DATA\mcedit" /E
echo Done!
set /p yesnol="Would you like to launch MCEdit now? [y/n]: "
if "%yesnol%"="y" (
set APPDATA=%DRIVE%:\MC\DATA
start %DRIVE%:\MC\DATA\mcedit\mcedit.exe
)
)
在您关闭驱动器之后,有任何帮助吗?
答案 0 :(得分:2)
导致脚本提前退出的问题是else
分支的最后一个if语句中的语法错误。如果从命令行运行脚本(而不是双击它),您将收到错误消息:
=" Y"这时出人意料。
确实,你最后的if语句是:
if "%yesnol%"="y" (
但cmd解析器需要一个双" ="签名(==
)进行比较,所以你应该:
if "%yesnol%"=="y" (
即使它不接受else分支也会看到它的原因是因为if-block(实际上,由( ... )
分隔的所有代码块)被解析为好像它是一个单个命令写在一行上(每个"子命令"在你的块中用&&
分隔)。因为解析器将处理整个" line"一次性,它将检测整个块内存在的任何语法错误。
除了语法错误之外,您在脚本中也犯了一些小错误。第一个是在代码块中声明标签实际上并不好。您已在:yes
分支的if-block中声明了else
标签。 if-block中的goto
将" destroy" if
- 上下文。您可能在代码中没有注意到,但请考虑以下示例:
@echo off
set var=Let's brake the if statement
IF DEFINED var (
echo The variable var exists
IF "%var%"=="Let's brake the if statement" goto :expected
echo The variable var is not what I would expect though.
echo You have to change it to something else...
goto :outside
:expected
echo I'm happy with its value. It is at least something I would expect
echo This is the end of the if-branch
) ELSE (
echo Strange ... the variable var is not defined.
echo Indeed: var="%var%"
)
:outside
rem just to get outside
您会期望输出
The variable var exists
I'm happy with its value. It is at least something I would expect
This is the end of the if-branch
但输出将是
The variable var exists
I'm happy with its value. It is at least something I would expect
This is the end of the if-branch
Strange ... the variable var is not defined.
Indeed: var="Let's brake the if statement"
goto
破坏了if-context。如前所述,cmd解析器将整个if-block解析为一个命令。这样看:你要求解析器放弃它正在处理的命令(整个if
块以及它刚检查的条件)并跳转到其他地方。其他地方在if
条件之后,所以它甚至不会再评估那个。所以,一旦你进入一个区块(特别是if-blocks和for-loops),不要使用goto
来忽略该区块内的某些代码,请使用if语句并将其放入要在if块中忽略的代码。跳出代码块的goto
不是问题,但从标签位于if块的那一刻起,它可能会导致意外的结果。
第二个错误是变量YesNoIn
和yesnol
。正如我所说的那样,将整个if块作为单个命令一次性解析。无法为变量赋予新值,并使用简单变量扩展%YesNoIn%
或%yesnol%
在同一命令中读取该新值。这个问题的解决方案是delayed expansion(链接也有一个例子)。当我写这个答案时,我看到@Josefz已经发布了answer延迟扩展,所以我不会在这里重复。但我建议您查看choice
命令。使用choice
命令,您不会需要延迟扩展。它只是设置了错误级别,并且有一种方法可以检查错误级别而不必担心延迟扩展:如果错误级别大于或等于n ,IF ERRORLEVEL n
将检查。最重要的是,choice
会自动验证用户是否输入了正确的值!
使用choice
而不是set /p
的脚本将如下所示:
echo What drive would you like to launch MCEdit on?
set /p DRIVE="Drive: "
if exist "%DRIVE%:\MC\DATA\mcedit\mcedit.exe" (
set APPDATA=%DRIVE%:\MC\DATA
start %DRIVE%:\MC\DATA\mcedit\mcedit.exe
) else (
echo You do not have MCEdit installed on this drive, would you like to install it?
choice /c YN
REM Y ==> errorlevel = 1 ; N ==> errorlevel = 2
if ERRORLEVEL 2 goto:menu
echo Choose the "mcedit.exe" file from a current installation on your pc.
pause
call "%DRIVE%\MC\DATA\FileViewer.bat"
xcopy "%OutCD%" "%DRIVE%:\MC\DATA\mcedit" /E
echo Done!
choice /c YN /m "Would you like to launch MCEdit now? "
if NOT ERRORLEVEL 2 (
set APPDATA=%DRIVE%:\MC\DATA
start %DRIVE%:\MC\DATA\mcedit\mcedit.exe
)
)
PS:使用choice
时,无需按Enter键。
编辑:第三个错误是变量APPDATA
的选择,你已经在用户的上下文中使用它,你可以看到{{3 }}
答案 1 :(得分:1)
后者if
中的比较运算符中存在简单的拼写错误。正确到if "%yesnol%"=="y"
答案 2 :(得分:0)
APPDATA
variable是否是一个好主意。:menu
标签。:label
nor :: label-like comment
inside a command block enclosed in ()
parentheses SETLOCAL EnableExtensions EnableDelayedExpansion
:::
:menu
:::
echo What drive would you like to launch MCEdit on?
set /p DRIVE="Drive: "
if exist "%DRIVE%:\MC\DATA\mcedit\mcedit.exe" (
set APPDATA=%DRIVE%:\MC\DATA
start %DRIVE%:\MC\DATA\mcedit\mcedit.exe
) else (
echo You do not have MCEdit installed on this drive, would you like to install it?
set /p YesNoIn="[y/n]: "
if /I "!YesNoIn!"=="y" (
echo Choose the "mcedit.exe" file from a current installation on your pc.
pause
call "%DRIVE%\MC\DATA\FileViewer.bat"
xcopy "%OutCD%" "%DRIVE%:\MC\DATA\mcedit" /E
echo Done^!
set /p yesnol="Would you like to launch MCEdit now? [y/n]: "
if /I "!yesnol!"="y" (
set APPDATA=%DRIVE%:\MC\DATA
start %DRIVE%:\MC\DATA\mcedit\mcedit.exe
)
) else goto:menu
)