22

我想从 PowerShell 启动一个 Java 程序并在控制台上打印结果。

我已按照此问题的说明进行操作: 使用 Start-Process 捕获标准输出和错误

但对我来说,这并没有像我预期的那样工作。我做错了什么?

这是脚本:

$psi = New-object System.Diagnostics.ProcessStartInfo
$psi.CreateNoWindow = $true
$psi.UseShellExecute = $false
$psi.RedirectStandardOutput = $true
$psi.RedirectStandardError = $true
$psi.FileName = 'java.exe'
$psi.Arguments = @("-jar","tools\compiler.jar","--compilation_level",   "ADVANCED_OPTIMIZATIONS", "--js", $BuildFile, "--js_output_file", $BuildMinFile)
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $psi
$process.Start() | Out-Null
$process.WaitForExit()
$output = $process.StandardOutput.ReadToEnd()
$output

$output变量始终为空(当然控制台上不会打印任何内容)。

4

3 回答 3

42

RedirectStandardError属性的文档建议最好在WaitForExit()调用之后进行ReadToEnd()调用。以下对我来说是正确的:

$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
于 2012-07-18T20:32:11.607 回答
18

小的变化,以便您可以在需要时选择性地打印输出。就好像您只是在寻找错误或警告消息一样,顺便说一下,基思用您的回复保存了我的培根……

$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)
于 2012-12-27T21:25:02.533 回答
4

这是对保罗答案的修改,希望它能解决截断的输出。我使用失败进行了测试,但没有看到截断。

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

10ms 的睡眠是为了避免在没有东西读的时候旋转 cpu。

于 2018-10-03T14:43:30.720 回答