PowerShell 假设您调用的每个外部程序仅提供string
s 超过它的输出流。
虽然这与现实相差不远,但人们可能希望从外部程序获取真实的字节。
为了实现这一目标,我们将“从头开始”创建一个新流程
$procInfo = New-Object System.Diagnostics.ProcessStartInfo -Property @{
FileName = "cmd.exe"
Arguments = "thing.bat"
RedirectStandardError = $true
RedirectStandardOutput = $true
UseShellExecute = $false
}
$proc = New-Object System.Diagnostics.Process
$proc.StartInfo = $procInfo
$proc.Start() | Out-Null
$proc.WaitForExit()
这为我们提供了StreamReader https://msdn.microsoft.com/en-us/library/system.io.streamreader(v=vs.110).aspx for StandardOutput
and StandardError
,当相应的重定向属性设置为$true
.
现在要获取流的内容,我们可以轻松使用ReadToEnd() https://msdn.microsoft.com/en-us/library/system.io.streamreader.readtoend(v=vs.110).aspx like $outContent = $proc.StandardOutput.ReadToEnd()
,但这只会再次给我们一个字符串。
A StreamReader https://msdn.microsoft.com/en-us/library/system.io.streamreader(v=vs.110).aspx为我们提供了以下方法(除其他外):
Read Method int Read(), int Read(char[] buffer, int index, int count)
ReadAsync Method System.Threading.Tasks.Task[int] ReadAsync(char[] buffer, int index, int count)
ReadBlock Method int ReadBlock(char[] buffer, int index, int count)
ReadBlockAsync Method System.Threading.Tasks.Task[int] ReadBlockAsync(char[] buffer, int index, int count)
ReadLine Method string ReadLine()
ReadLineAsync Method System.Threading.Tasks.Task[string] ReadLineAsync()
ReadToEnd Method string ReadToEnd()
ReadToEndAsync Method System.Threading.Tasks.Task[string] ReadToEndAsync()
只需创建并传递一个char[]
缓冲到Read() https://msdn.microsoft.com/en-us/library/system.io.streamreader.read(v=vs.110).aspx并像你想要的那样使用它:
$length = $proc.StandardOutput.Length
$s = New-Object 'char[]' $length
$proc.StandardOutput.Read($s, 0, $length - 1)
第二种更简单但灵活性较差的解决方案:
如果将文件写入磁盘没有问题,您可以轻松地将程序的标准输出重定向到一个文件-Encoding Oem
并再次读入Get-Content
:
& .\thing.bat | Out-File -FilePath "C:/tmp/out.txt" -Encoding Oem
$rawContent = Get-Content -Path "C:/tmp/out.txt" -Encoding Oem