【问题标题】:Batch not exiting Loop after Windows 10 April 2018 UpdateWindows 2018 年 4 月 10 日更新后批次未退出循环
【发布时间】:2018-05-05 22:19:19
【问题描述】:

我使用批处理脚本连接笔记本电脑上的网络驱动器,作为标准方式(通过驱动器映射)尝试在 WIFI 连接之前连接它们,因此并不总是成功。该脚本过去几乎可以运行 3 年,没有任何问题。

@echo off
net use * /del /yes
net use /persistent:no

:Loop
for /L %%A in (1,1,50) do (
ping DiskStation | find /i "bytes=" && goto Connected
ping LocalHost -n 3 > nul
ECHO %%A
)
rundll32 user32.dll,MessageBeep -1
goto Finish

:Connected
ping LocalHost -n 3 > nul
net use X: \\DiskStation\NaszePhotoVideo
net use Z: \\DiskStation\NaszeDane

:Finish

在 2018 年 4 月 10 日 Windows 更新后,脚本已停止工作。似乎它无法在ping DiskStation | find /i "bytes=" && goto Connected 处退出循环。

当我在其他命令行窗口中 ping DiskStation 时,该命令的标准结果一切正常。

【问题讨论】:

    标签: windows shell batch-file command-line


    【解决方案1】:

    for 循环通常可以使用命令goto 退出,但for /L 循环不能。在 Windows XP 或任何更高版本的 Windows 上,只需使用以下命令行从命令提示符窗口中运行批处理文件,就可以看到这种意外行为:

    @for /L %%A in (1,1,5) do if %%A == 3 @echo EQUAL & goto :EOF
    

    输出是:

    if 1 == 3
    if 2 == 3
    if 3 == 3
    EQUAL
    if 4 == 3
    if 5 == 3
    

    命令goto :EOF 对执行没有影响。尽管在第三次迭代中if 条件为真并且echo 输出EQUAL,但循环仍运行了五次,但goto 不被Windows 命令处理器执行。

    在这种情况下,解决方案不使用for /L

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    set "LoopCount=0"
    set "SysPath=%SystemRoot%\System32"
    %SysPath%\net.exe use * /del /yes >nul
    
    :Loop
    %SysPath%\ping.exe -n 1 DiskStation | %SysPath%\find.exe /I "bytes=" >nul 2>&1 && goto Connected
    %SysPath%\ping.exe 127.0.0.1 -n 3 >nul
    set /A LoopCount+=1
    echo %LoopCount%
    if not %LoopCount% == 50 goto Loop
    %SysPath%\rundll32.exe user32.dll,MessageBeep -1
    goto Finish
    
    :Connected
    %SysPath%\ping.exe 127.0.0.1 -n 3 >nul
    %SysPath%\net.exe use X: \\DiskStation\NaszePhotoVideo /persistent:no
    %SysPath%\net.exe use Z: \\DiskStation\NaszeDane       /persistent:no
    
    :Finish
    endlocal
    

    使用跳转标签编码的循环、使用算术表达式计数的环境变量、字符串比较条件和跳转到标签的速度比for /L 慢,但这在此任务中并不重要。

    要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

    • echo /?
    • endlocal /?
    • find /?
    • for /?
    • goto /?
    • net /?
    • net use /?
    • ping /?
    • set /?
    • setlocal /?

    【讨论】:

    • 我还注意到 Ping 现在需要小写的主机名,即使它在 Synology 上设置为“DiskStation”。 Net.exe 仍然接受正确的 PascalCase 名称,因为它实际上是命名的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 2016-07-11
    相关资源
    最近更新 更多