I'm trying to process the output of a Process using a job because I need it to be parallel but the System.IO.StreamReader turns into a Deserialized.System.IO.StreamReader that doesn't have any way of reading from it and I can't find any documentation on it (Google and Bing give 0 results). It gets strange. It stays a System.IO.StreamReader if I don't try to read from it in the block.
I'm still relatively new to PowerShell and not sure if this is expected behavior.
- PowerShell: 5.1.14393.5127
- .NET: 4.7.3946.0
Given
function runProg(
[parameter(Mandatory)][string]$exe,
[object[]]$params=@(),
[switch]$redirectOutput,
[switch]$redirectError,
[switch]$redirectInput
){
$args= ($params.ForEach({ if($_ -is [System.IO.FileSystemInfo]){ ('"{0}"' -f $_.FullName) } elseif(($_.ToString().Contains(' '))){ ('"{0}"' -f $_) }else{ $_ } }) -join ' ')
Write-Host "$exe $args"
if ($redirectOutput -or $redirectError -or $redirectInput){
$pinfo= New-Object System.Diagnostics.ProcessStartInfo;
$pinfo.UseShellExecute= $false; #needed to redirect outputs and inputs
$pinfo.FileName= $exe
$pinfo.CreateNoWindow= $true
$pinfo.RedirectStandardInput= $redirectInput
$pinfo.RedirectStandardOutput= $redirectOutput
$pinfo.RedirectStandardError= $redirectError
$pinfo.Arguments= $args
$proc= [System.Diagnostics.Process]::Start($pinfo);
}else{
$proc= Start-Process -FilePath $exe -PassThru -NoNewWindow -ArgumentList $args
}
$handle = $proc.Handle # force proc.Handle to populate https://stackoverflow.com/a/23797762/1479211
return $proc
}
$p= runProg -redirectOutput 'powershell.exe' @((Get-Item 'test-long-output.ps1'))
The below gets the expected System.IO.StreamReader
$streamReader= {
param($stream)
Write-Host "`$stream.GetType" $stream.GetType().FullName
Write-Host "`$stream.ReadLine?" ($null -ne $stream.ReadLine)
}
$streamJob= Start-Job -ArgumentList @($p.StandardOutput) -ScriptBlock $streamReader
The below gets the Deserialized.System.IO.StreamReader and errors on the missing ReadLine method.
$streamReader= {
param($stream)
Write-Host "`$stream.GetType" $stream.GetType().FullName
Write-Host "`$stream.ReadLine?" ($null -ne $stream.ReadLine)
do{
$line= $stream.ReadLine();
Write-Output $line
}while($line -ne $null)
}
$streamJob= Start-Job -ArgumentList @($p.StandardOutput) -ScriptBlock $streamReader