我正在尝试调试PowerShell ISE中的脚本,但我正在运行一个问题,其中一行的正常输出被ISE解释为错误
我已经能够简化这个问题的复制: 我在https://www.openssl.org/related/binaries.html获得了openssl的任何版本(我使用链接存储库http://slproweb.com/products/Win32OpenSSL.html中的1.0.2d x86对其进行了测试)
我打开Powershell ISE,导航到exe所在的位置并执行以下操作:
$ErrorActionPreference = "Stop"
$env:OPENSSL_CONF = ((Resolve-Path "openssl.cfg").Path)
&openssl.exe genrsa
输出为红色,如下所示:
openssl.exe : Loading 'screen' into random state - done
At line:1 char:1
+ &C:\Trayport\OpenSsl\openssl.exe genrsa
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Loading 'screen...om state - done:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Generating RSA private key, 2048 bit long modulus
如果我在普通的PowerShell命令窗口中运行它,输出是相同的但是是白色的并且不被视为错误
Loading 'screen' into random state - done
Generating RSA private key, 2048 bit long modulus
我尝试使用2>& 1或使用ErrorPreference参数包围调用(如PowerShell ISE throws an error on git checkout中所述),但仍然失败
尝试/捕捉所有异常确实有效,但我不愿意,如果我可以避免它。
我尝试使用PowerShell版本3.0和4.0
编辑:如果您使用$ErrorActionPreference = "SilentlyContinue"
,它确实会使错误无效,但您会失去对输出的访问权限,而且合法问题也会消失
答案 0 :(得分:3)
Powershell将任何转储解释为错误通道,作为应用程序端发生的错误,因此它会停止脚本超过该点。您应该在调用2>&1
的行中添加openssl.exe
,以便应用程序的标准错误不会被Powershell捕获并解释为实际错误。
$ErrorActionPreference = "Stop"
$env:OPENSSL_CONF = ((Resolve-Path "openssl.cfg").Path)
& openssl.exe genrsa 2>&1
更新:它是无法治愈的,Powershell ISE会拦截标准错误通道进入Write-Error
并触发停止。解决方法here包括将生成错误通道输出的外部应用程序包装到具有$ErrorActionPreference
的本地覆盖的脚本块中,如下所示:
& {
$ErrorActionPreference='silentlycontinue'
openssl.exe genrsa 2>&1
}
答案 1 :(得分:3)
我找到了一个有效的解决方案。
正如问题编辑中指定的那样,设置$ErrorActionPreference = "SilentlyContinue"
是一个错误的解决方案,因为在这种情况下,PowerShell相当于吞下所有错误,并且它还删除了对实际输出的访问权限这个过程。
但是,在使用实际返回合法错误的命令参数进行测试时,我注意到在这种情况下我会得到一个非0 $ LASTEXITCODE(注意任何有类似问题的人:这实际上是特定于openssl.exe,对于你打电话的任何一个应用程序,情况可能并非如此。
所以我决定依赖进程退出代码来决定是否应该将stderr视为实际错误。
Capturing standard out and error with Start-Process提供了一个解决方案来保持进程的输出存活,所以:
$processStartInfo = New-Object System.Diagnostics.ProcessStartInfo
$processStartInfo.FileName = "openssl.exe"
$processStartInfo.RedirectStandardError = $true
$processStartInfo.RedirectStandardOutput = $true
$processStartInfo.UseShellExecute = $false
$processStartInfo.Arguments = "genrsa"
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $processStartInfo
$process.Start() | Out-Null
$process.WaitForExit()
$standardError = $process.StandardError.ReadToEnd()
if ($process.ExitCode) {
Write-Error $standardError
} else {
Write-Host $standardError
}
答案 2 :(得分:0)
Invoke-Expression ".\openssl.exe req -new -nodes -out c:\test\certs\rui.csr -keyout c:\test\certs\rui.key -config c:\test\certs\esxi.cfg" 2>&1