不幸的是,批处理脚本中的 "call" 或 <str> 从变量中删除了某些字符

"call" or <str> in batch script unfortunately removes certain characters from a variable

我不明白为什么下面的批次:

REM echo off
setlocal
set u64=aDI0NDcxOQ==
set p64=SGZzemxwNzc3
call :atob usr "%u64%"
call :atob pwd "%p64%"
schtasks /Run /S aaa.bbb.ccc.ddd /U %usr% /P %pwd% /TN "My Scheduler Task Name"
goto :EOF

:atob <var_to_set> <str>
for /f "delims=" %%I in (
   'powershell "[Text.Encoding]::UTF8.GetString([convert]::FromBase64String(\"%~2\"))"'
) do set %~1=%%I
goto :EOF

删除 u64 的最后 2 个“=”字符,如您所见,结果如下:

C:\Users\lambda>REM echo off
C:\Users\lambda>setlocal
C:\Users\lambda>set u64=aDI0NDcxOQ==
C:\Users\lambda>set p64=SGZzemxwNzc3
C:\Users\lambda>call :atob usr "aDI0NDcxOQ=="
C:\Users\lambda>for /F "delims=" %I in ('powershell "[Text.Encoding]::UTF8.GetString([convert]::FromBase64String(\"aDI0NDcxOQ \"))"') do set usr=%I
C:\Users\lambda>set usr=Exception calling "FromBase64String" with "1" argument(s): "Longueur non
C:\Users\lambda>set usr=valide pour un tableau de caractères Base 64 ou une chaîne."
C:\Users\lambda>set usr=At line:1 char:1
C:\Users\lambda>set usr=+ [Text.Encoding]::UTF8.GetString([convert]::FromBase64String("aDI0NDcxOQ "))
C:\Users\lambda>set usr=+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Users\lambda>set usr=    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
C:\Users\lambda>set usr=    + FullyQualifiedErrorId : FormatException
C:\Users\lambda>set usr=
C:\Users\lambda>goto :EOF
C:\Users\lambda>call :atob pwd "SGZzemxwNzc3"
C:\Users\lambda>for /F "delims=" %I in ('powershell "[Text.Encoding]::UTF8.GetString([convert]::FromBase64String(\"SGZzemxwNzc3\"))"') do set pwd=%I
C:\Users\lambda>set pwd=Hfszlp777
C:\Users\lambda>goto :EOF
C:\Users\lambda>schtasks /Run /S aaa.bbb.ccc.ddd /U   /P Hfszlp777 /TN "My Scheduler Task Name"
Erreur : Syntaxe incorrecte. Valeur attendue pour '/U'.
Entrez "SCHTASKS /RUN /?" pour afficher la syntaxe.
C:\Users\lambda>goto :EOF

如果没有最后2个'='字符,我的Base54值u64的字符数不是4的倍数,因此无法解码。 我们可以在输出中看到它在 p64 上运行良好。 usr 只存储一个 space... 我现在想坚持使用 .bat 文件,而不是 .ps1 脚本。 谢谢你的帮助。 我尝试了几种用“”包围的组合,但到目前为止结果相同。

您的问题不在于 call,而在于解析器在准备要执行的命令时如何决定将什么作为定界符来处理。

虽然对于这种情况有一些选项(转义字符或延迟扩展),但最简单的选项(从批处理的角度来看)可能是将对变量的访问包装在 for 可替换参数中

:atob <var_to_set> <str>
    for %%V in ("%~2") do for /f "delims=" %%I in ('
        powershell "[Text.Encoding]::UTF8.GetString([convert]::FromBase64String(\"%%~V\"))"
    ') do set "%~1=%%I"
    goto :EOF

FromBase64String(\"%~2\") 更改为 FromBase64String('%~2') 也解决了我测试中的问题。我不能说为什么等号被转换为 space,但我可以说在 PowerShell 中,单引号字符串被视为文字,而双引号字符串允许评估字符串的内容。

在命令提示符下,尝试

powershell "\"$null\""

然后尝试

powershell "'$null'"

并观察不同的行为。

或者,您可以在批处理子例程中将变量分配给 %~2,然后在 PowerShell 的 env: 范围内引用它。

:atob <var_to_set> <str>
set "str=%~2"
for /f "delims=" %%I in (
   'powershell "[Text.Encoding]::UTF8.GetString([convert]::FromBase64String($env:str))"'
) do set "%~1=%%I"
goto :EOF