mkl*_*nt0 7 powershell cmd batch-file exit-code parameter-passing
我怀疑没有好的解决方案,但也许我忽略了一些事情:
我所追求的是一种方法:
(a) 从 PowerShell 调用批处理文件,其方式可以在 PowerShell 自动变量中稳健地$LASTEXITCODE反映其(隐式或显式)退出代码。
值得注意的是,调用以 , 退出的批处理文件whoami -nosuch || exit /b应该会导致$LASTEXITCODE反映 的whoami退出代码,即1。当您从 PowerShell 调用批处理文件(按名称或路径)时,情况并非如此:退出代码为0(相反,在cmd.exe会话内部设置为%ERRORLEVEL% )1。
另请注意,调用应与 PowerShell 的输出流保持集成,因此我并不是在寻找基于System.Diagnostics.Process.
此外,我不知道或无法控制调用的批处理文件 - 我正在寻找通用的解决方案。
(b) 传递给批处理文件的双引号参数不会以任何方式被更改,并且cmd.exe的行为不会以任何方式被修改;尤其:
^字符不应该(见下文)。/V:ON选项。我知道如何解决(a)的唯一方法是通过调用批处理文件cmd /c call。
不幸的是,这违反了要求 (b),因为在参数中使用call看似总是双倍的^字符。(并且,相反,不使用callthen 不会可靠地报告退出代码)。
有没有办法同时满足要求呢?
请注意,PowerShell 只是这里的信使:问题在于cmd.exe,任何从会话外部调用批处理文件的人cmd.exe都会面临同样的问题。
示例(PowerShell 代码):
# Create a (temporary) batch file that echoes its arguments,
# provokes an error, and exits with `exit /b` *without an explicit argument*.
'@echo off & echo [%*] & whoami -nosuch 2>NUL || exit /b' | Set-Content test.cmd
# Invoke the batch file and report the exit code.
.\test.cmd "a ^ 2"; $LASTEXITCODE
Run Code Online (Sandbox Code Playgroud)
输出应该是:
["a ^ 2"]
1
Run Code Online (Sandbox Code Playgroud)
然而,实际上并没有报告退出代码:
["a ^ 2"]
0 # !! BROKEN
Run Code Online (Sandbox Code Playgroud)
如果我用 withcmd /c call .\test.cmd调用,退出代码是正确的,但^字符会加倍:
PS> cmd /c call .\test.cmd "a ^ 2"; $LASTEXITCODE
["a ^^ 2"] # !! BROKEN
1 # OK
Run Code Online (Sandbox Code Playgroud)
我不知道为什么会这样,但它确实有效:
cmd /c '.\test.cmd "a ^ 2" & exit'
$LASTEXITCODE
Run Code Online (Sandbox Code Playgroud)
输出:
["a ^ 2"]
1
Run Code Online (Sandbox Code Playgroud)