批处理中for/call/errorlevel返回值

因为做软件代码签名,在做脚本时,发现批处理脚本真是坑爹货,太多问题,故在以下记录一下。

rem @echo off

rem 必须使用setlocal,否则for()do(call)语句call函数返回值是无法正常返回的,故务必加上此句。
setlocal enabledelayedexpansion
set path_script=%~dp0
echo %path_script%

set myfile=%~1
set "myfile=%myfile:"=%"
for %%i in ("http://sha256timestamp.ws.symantec.com/sha256/","http://tsa.wosign.com/timestamp","http://timestamp.digicert.com") do (
    call :signmain "%%i" "%myfile%"

    rem 因为for语句的影响,必须和setLocal一起使用,才能返回errorlevel.
    rem 因为是延后扩展返回值,不能使用%errorlevel%必须使用双叹号。
    set retval=!errorlevel! 
    echo "retval:!retval!"
rem rem lss equ neq gtr geq leq
    if !retval! neq 0 (
        rem 必须加上/b参数,否则会是脚本退出,而不是call调用返回。
        exit /b 0 
    ) 
)

rem 此处不需要使用双叹号,能直接返回值。
call :signmain "a" "b"
echo "errorlevelLast:%errorlevel%"
exit /b 12

:signmain
set timeserver=%~1
set "timeserver=%timeserver:"=%"
set signfile=%~2
set "signfile=%signfile:"=%"
set /a num=0
:loop
echo "try to do the %num% time"
echo "timeserver:%timeserver%"
echo "signfile:%signfile%"
signtool sign /v /fd sha256 /sha1 8cff6301fbee55b05364e6f11d2e5ed090abcdef /tr "%timeserver%" /td sha256 "%signfile%"
set errcode=%errorlevel%
echo "errorlevel:%errcode%"
if %errcode% == 0 (
    echo "success:%signfile%"
    echo "-------------------------------------------------------------------"
    exit /b 0
) else (
    set /a num+=1
    if %num% lss 2 goto :loop
)
set /a retval=10+%num%
exit /b %retval%