如果存在,我的批处理窗口在运行时关闭

时间:2017-01-12 18:22:31

标签: batch-file cmd

我有一个小程序,当我运行"如果存在"它关闭了,有人可以告诉我为什么吗?我检查了语法错误,没有(我想),我会在这里粘贴我的代码,看看你能做些什么。

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
    )
)

在您关闭驱动器之后,有任何帮助吗?

3 个答案:

答案 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块的那一刻起,它可能会导致意外的结果。

第二个错误是变量YesNoInyesnol。正如我所说的那样,将整个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)

  1. 我不确定更改APPDATA variable是否是一个好主意。
  2. 代码中缺少:menu标签。
  3. 重要:阅读并应用http://ss64.com/nt/delayedexpansion.html
  4. Never use :label nor :: label-like comment inside a command block enclosed in () parentheses
  5. 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
    )