我得到了
的输出此操作仅对产品有效 当前已安装。
并且想测试该条件以及其他条件,但是 $stdout gettype 是一个字符串,但是当我测试上面的引用 $stdout -eq $null 或 $stdout -eq 时,它总是失败。流是否必须以某种方式转换?如何与 $null 和其他字符串进行比较?
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = 'msiexec'
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "/x {22AD1D41-EDA0-4387-BF16-9045CE734FAD} /quiet /norestart /l*v `"C:\temp\msi123_MSI_UNINSTALL.log`""
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd() | Out-String
$stderr = $p.StandardError.ReadToEnd()
msiexec.exe
在几个方面都很不寻常:
它是一个GUI子系统应用程序(而不是控制台子系统应用程序),但具有广泛的CLI(支持许多参数)。
如果后者是以编程方式捕获,它仅输出到其stdout流(而不是打印到调用进程的控制台)。
当
msiexec.exe
确实将输出发送到stdout时,它使用“Unicode”编码,即UTF-16LE编码 - 它不使用系统的活动遗留OEM代码页,这是console应用程序通常所做的事情。
如果您只是想知道是否生成了 any stdout 或 stderr,最简单的方法是利用 PowerShell 的 隐式布尔强制转换,它将
$null
和 空字符串 视为 $false
:
if (-not $stdout) { 'No stdout output was produced.' }
如果您确实想捕获特定的标准输出(以及假设的标准错误)输出并正确解码,请使用以下命令:
$pinfo = [System.Diagnostics.ProcessStartInfo] @{
FileName = 'msiexec'
Arguments = "/x {22AD1D41-EDA0-4387-BF16-9045CE734FAD} /quiet /norestart /l*v `"C:\temp\msi123_MSI_UNINSTALL.log`""
UseShellExecute = $false
RedirectStandardError = $true
RedirectStandardOutput = $true
StandardOutputEncoding = [System.Text.Encoding]::Unicode
StandardErrorEncoding = [System.Text.Encoding]::Unicode
}
$p = [System.Diagnostics.Process]::Start($pinfo)
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
注:
.StandardOutputEncoding
和
.StandardErrorEncoding
属性设置为 [System.Text.Encoding]::Unicode
,即 UTF-16LE。
,
System.Diagnostics.ProcessStartInfo
对象是通过哈希表初始化其属性来隐式构造的;类似地,
System.Diagnostics.Process
实例是通过将前一个实例传递给后一个类型的静态
System.Diagnostics.Process.Start
方法来创建的。