Errorlevel 变量在错误后没有改变..?

Errorlevel variable not changing after error..?

我正在尝试编写一个脚本,该脚本将 运行 始终在后台运行。它的目标是检测 USB 闪存驱动器、外部硬盘驱动器或您连接到计算机的任何可写设备。一旦它检测到一个,它就会在这个设备的根目录复制一个文件。这是我的代码(回声线用于更清晰的调试):

@echo off
:loop
for /F "tokens=1*" %%a in ('fsutil fsinfo drives') do (
    for %%c in (%%b) do (
        for /F "tokens=4" %%d in ('fsutil fsinfo drivetype %%c') do (
            if %%d equ amovible (
                echo Found out that %%c is removable. Trying to echo the content...
                dir %%c >NUL
                echo Error: %errorlevel%
                if %errorlevel%==0 (
                    echo Errorlevel is 0! Copying...
                    if not exist %%c\test.txt (
                        copy .\test.txt %%c\test.txt
                        echo.
                    )
                ) else (
                    echo Errorlevel isn't 0. Looks like the drive isn't here, or is unavailable. Aborting copying...
                  echo.
                )
            )
        )
    )
)
TIMEOUT 2
goto :loop

这就是问题所在。条件 "if %errorlevel%==0" 应该检查 "dir %%c >NUL" 命令是否成功,所以如果 errorlevel 为 0,则表示设备上有文件系统,它不像空卡 reader 或空的软盘驱动器。问题是当我执行我的代码时,errorlevel 总是 0,我不明白为什么("echo Error: %errorlevel%" 告诉它)。所以文件 test.txt 确实复制到我的 USB 闪存驱动器上,所以这基本上可以工作,问题是当将文件复制到我的软盘驱动器时,出现一个错误框,说我应该插入一个设备reader,这就是我要进行此错误级别检查的原因。

所以如果有人有解决方案,请帮忙,我真的被卡住了。 提前致谢。

您需要使用 delayed expansion (!ErrorLevel!),否则,您会得到 ErrorLevel 整个括号块(即嵌套 for 循环结构)被解析。由于感叹号被延迟扩展功能消耗,我只会在实际需要的地方启用它,如下所示:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
:loop
for /F "tokens=1*" %%a in ('fsutil fsinfo drives') do (
    for %%c in (%%b) do (
        for /F "tokens=4" %%d in ('fsutil fsinfo drivetype %%c') do (
            if "%%d"=="amovible" (
                echo Found out that %%c is removable. Trying to echo the content...
                dir "%%~c" > nul
                setlocal EnableDelayedExpansion
                echo Error: !ErrorLevel!
                if !ErrorLevel! equ 0 (
                    endlocal
                    echo ErrorLevel is 0! Copying...
                    if not exist "%%~c\test.txt" (
                        copy ".\test.txt" "%%~c\test.txt"
                        echo/
                    )
                ) else (
                    endlocal
                    echo ErrorLevel isn't 0. Looks like the drive isn't here, or is unavailable. Aborting copying...
                    echo/
                )
            )
        )
    )
)
timeout 2
goto :loop
endlocal

或者,由于 dir 永远不会将 ErrorLevel 设置为负值,您也可以使用 if not errorlevel 1 syntax,即 "if not ErrorLevel is greater than or equal to 1",因此 "if ErrorLevel is less than 1"(显然你不能回显实际的 ErrorLevel 值):

                ...
                dir "%%~c" > nul
                if not ErrorLevel 1 (
                    echo ErrorLevel is 0! Copying...
                    if not exist "%%~c\test.txt" (
                        copy ".\test.txt" "%%~c\test.txt"
                        echo/
                    )
                ) else (
                    echo ErrorLevel isn't 0. Looks like the drive isn't here, or is unavailable. Aborting copying...
                    echo/
                )
                ...

另一种方法是使用 conditional execution operators && and/or ||,它让后面的命令或块仅在前面的命令 returns 退出代码为零的情况下执行(大多数情况下,也有这里的 dir 命令,退出代码与 ErrorLevel):

的值相同
                ...
                dir "%%~c" > nul && (
                    echo ErrorLevel is 0! Copying...
                    if not exist "%%~c\test.txt" (
                        copy ".\test.txt" "%%~c\test.txt"
                        echo/
                    )
                ) || (
                    echo ErrorLevel isn't 0. Looks like the drive isn't here, or is unavailable. Aborting copying...
                    echo/
                )
                ...