批处理文件循环问题

时间:2015-03-02 23:23:48

标签: windows loops batch-file command

我的批处理文件中存在循环问题。使用set命令时,我给用户两个选择。第一个选项工作正常,但第二个选项被忽略,除非进行循环功能重新提问。然后它接受第二个选项的输入。

:WithAccess
cls
If not exist "C:\Program Files (x86)\Microsoft Office\Office15\Winword.exe" (
    goto UninstallViewers
    :WithAccess2
    echo Installing MS Office 2013 x32 With Access...
    start /wait "" "MS Office 2013 x32 Installers\MSOfficeWithAccess"
    echo Installation Complete.
) Else (
    echo Microsoft Office 2013 might already be installed.
    set /p op4=Do you want to run installer anyway? [Y/N]:
    If "%op4%"=="y" goto WithAccess2
    If "%op4%"=="n" goto end
    echo That's not a valid option.
    goto WithAccess
)

所以,在这个if语句的“Else”部分,当用户选择选项2或“n”时,它将忽略它并转移到它之后的任何代码。在这种情况下,它循环回到此代码段的开头。但是在循环之后,它现在接受用户输入并正确跳转到“结束”标签。

在玩完之后,我发现删除这个段周围的标签可以修复它,但是如果用户发出错误就会这样做,它就不会循环回来并重新提问。最初我的“Else”声明看起来像这样:

Else (
    echo Microsoft Office 2013 might already be installed.
    :Loop2
    set /p op4=Do you want to run installer anyway? [Y/N]:
    If "%op4%"=="y" goto WithAccess2
    If "%op4%"=="n" goto end
    echo That's not a valid option.
    goto Loop2
)

因此理想情况下它会循环同一个问题,但显然会出现同样的问题。我试图寻找答案,但很难找到这样一个特定的编码问题。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

将标签放在括号内的代码块中bad practice。如果您goto label且该标签位于代码块内,则执行线程会落在标签上,认为它不再位于代码块内,并且会出现问题。您应该重新编写脚本流程的逻辑。将标签移到任何括号之外,如果要调用函数,请考虑使用call而不是goto,然后返回以继续解析下一行。你甚至可能会发现它对return values from your functions不时有用。另外,使用if /i进行不区分大小写的测试。

:WithAccess
cls
If not exist "C:\Program Files (x86)\Microsoft Office\Office15\Winword.exe" (
    call :UninstallViewers
) Else (
    echo Microsoft Office 2013 might already be installed.
    set /p "op4=Do you want to run installer anyway? [Y/N]: "
    setlocal enabledelayedexpansion
    If /I "!op4!"=="y" goto WithAccess2
    If /I "!op4!"=="n" goto :EOF
    endlocal
    echo That's not a valid option.
    goto WithAccess
)

:WithAccess2
echo Installing MS Office 2013 x32 With Access...
start /wait "" "MS Office 2013 x32 Installers\MSOfficeWithAccess"
echo Installation Complete.

:: end main runtime
goto :EOF

:UninstallViewers
:: (or whatever code you have to do the uninstalling)
wmic product where "name like '%%viewer%%' and vendor like '%%microsoft%%'" call uninstall
goto :EOF