Powershell: Capturing standard out and error with Process object

前端 未结 3 1051
轮回少年
轮回少年 2020-12-02 23:47

I want to start a Java program from PowerShell and get the results printed on the console.

I have followed the instructions of this question: Capturing standard out

相关标签:
3条回答
  • 2020-12-03 00:12

    The docs on the RedirectStandardError property suggests that it is better to put the WaitForExit() call after the ReadToEnd() call. The following works correctly for me:

    $psi = New-object System.Diagnostics.ProcessStartInfo 
    $psi.CreateNoWindow = $true 
    $psi.UseShellExecute = $false 
    $psi.RedirectStandardOutput = $true 
    $psi.RedirectStandardError = $true 
    $psi.FileName = 'ipconfig.exe' 
    $psi.Arguments = @("/a") 
    $process = New-Object System.Diagnostics.Process 
    $process.StartInfo = $psi 
    [void]$process.Start()
    $output = $process.StandardOutput.ReadToEnd() 
    $process.WaitForExit() 
    $output
    
    0 讨论(0)
  • 2020-12-03 00:20

    Here is a modification to paul's answer, hopefully it addresses the truncated output. i did a test using a failure and did not see truncation.

    function Start-ProcessWithOutput
    {
        param ([string]$Path,[string[]]$ArgumentList)
        $Output = New-Object -TypeName System.Text.StringBuilder
        $Error = New-Object -TypeName System.Text.StringBuilder
        $psi = New-object System.Diagnostics.ProcessStartInfo 
        $psi.CreateNoWindow = $true 
        $psi.UseShellExecute = $false 
        $psi.RedirectStandardOutput = $true 
        $psi.RedirectStandardError = $true 
        $psi.FileName = $Path
        if ($ArgumentList.Count -gt 0)
        {
            $psi.Arguments = $ArgumentList
        }
        $process = New-Object System.Diagnostics.Process 
        $process.StartInfo = $psi 
        [void]$process.Start()
        do
        {
    
    
           if (!$process.StandardOutput.EndOfStream)
           {
               [void]$Output.AppendLine($process.StandardOutput.ReadLine())
           }
           if (!$process.StandardError.EndOfStream)
           {
               [void]$Error.AppendLine($process.StandardError.ReadLine())
           }
           Start-Sleep -Milliseconds 10
        } while (!$process.HasExited)
    
        #read remainder
        while (!$process.StandardOutput.EndOfStream)
        {
            #write-verbose 'read remaining output'
            [void]$Output.AppendLine($process.StandardOutput.ReadLine())
        }
        while (!$process.StandardError.EndOfStream)
        {
            #write-verbose 'read remaining error'
            [void]$Error.AppendLine($process.StandardError.ReadLine())
        }
    
        return @{ExitCode = $process.ExitCode; Output = $Output.ToString(); Error = $Error.ToString(); ExitTime=$process.ExitTime}
    }
    
    
    $p = Start-ProcessWithOutput "C:\Program Files\7-Zip\7z.exe" -ArgumentList "x","-y","-oE:\PowershellModules",$NewModules.FullName -verbose
    $p.ExitCode
    $p.Output
    $p.Error
    

    the 10ms sleep is to avoid spinning cpu when nothing to read.

    0 讨论(0)
  • 2020-12-03 00:27

    Small variation so that you can selectively print the output if needed. As in if your looking just for error or warning messages and by the way Keith you saved my bacon with your response...

    $psi = New-object System.Diagnostics.ProcessStartInfo 
    $psi.CreateNoWindow = $true 
    $psi.UseShellExecute = $false 
    $psi.RedirectStandardOutput = $true 
    $psi.RedirectStandardError = $true 
    $psi.FileName = 'robocopy' 
    $psi.Arguments = @("$HomeDirectory $NewHomeDirectory /MIR /XF desktop.ini /XD VDI /R:0 /W:0 /s /v /np") 
    $process = New-Object System.Diagnostics.Process 
    $process.StartInfo = $psi 
    [void]$process.Start()
    do
    {
       $process.StandardOutput.ReadLine()
    }
    while (!$process.HasExited)
    
    0 讨论(0)
提交回复
热议问题