[英]How to get original binary data from external command output in PowerShell?
我在这里读到,当你在 powershell 中运行外部命令时,它们的输出总是被解释为字符串或字符串数组: https : //stackoverflow.com/a/35980675/983442
我正在尝试处理来自外部命令的二进制输出,但似乎 PowerShell 只能给我字符串。
这让我想知道,使用什么编码将二进制数据转换为字符串? 而且,它如何解释换行符以将二进制数据划分为字符串数组? 它似乎仅在\\n
字符上拆分,但我确定它也会在\\r\\n
上拆分。
甚至有一种可靠的方法来获取powershell给我的字符串并将它们转换回字节数组吗?
例如,假设我有一个包含以下内容的批处理文件,将其thing.bat
:
@echo off
type image.jpg
然后我运行以下powershell:
PS> $x = & .\thing.bat
PS> $x.gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS> $x[0].gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
PS> $x.count
36
有了$x
变量后,如何在 PowerShell 中可靠地重新创建此 image.jpg?
PowerShell 假设,您调用的每个外部程序仅在其输出流上提供string
。 虽然这与现实相去甚远,但人们可能希望从外部程序中获取实际字节。 为了实现这一目标,我们将“从头开始”创建一个新流程
$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()
当相应的 Redirect 属性设置为$true
时,它为我们提供了StandardOutput
和StandardError
的StreamReader
。
现在要获取流的内容,我们可以轻松地使用ReadToEnd()
如$outContent = $proc.StandardOutput.ReadToEnd()
,但这将再次给我们一个字符串。
StreamReader
为我们提供了以下方法(其中包括):
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()
并按照需要使用它:
$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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.