问题描述
我正在使用 PowerShell 脚本来执行控制台应用程序,并且我正在尝试从那里重定向标准输出和标准错误.我使用的代码如下:
I am using a PowerShell script to execute a console application and I am trying to redirect the standard output and the standard error from there.The code I am using is the following:
$ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo
$ProcessInfo.FileName = "myExe.exe"
$ProcessInfo.Arguments = "bla bla bla"
$ProcessInfo.RedirectStandardError = $true
$ProcessInfo.RedirectStandardOutput = $true
$ProcessInfo.UseShellExecute = $false
$Process = New-Object System.Diagnostics.Process
$Process.StartInfo = $ProcessInfo
$Process.Start() | Out-Null
$output = $Process.StandardOutput.ReadToEnd()
$errors = $Process.StandardError.ReadToEnd()
$Process.WaitForExit()
$output
$errors
return $Process.ExitCode
到目前为止一切顺利,如果出现错误,我可以看到它被重定向到我的 PowerShell 控制台,如果我有输出,它也会被重定向.问题是这个过程需要 10 分钟,同时我们不知道发生了什么.
So far so good, if I have an error I can see it redirected into my PowerShell console and if I have output it is also redirected.The issue is that this process takes 10 minutes and in the meantime we have no clue of what is going on.
在 PowerShell 中有什么方法可以在进程运行时流式传输输出和错误的内容?在纯 .NET 中我们可以订阅 Process 类的事件,我可以在 PowerShell 中这样做吗?
Is there any way in PowerShell I can stream the content of the Output and the Error while the process is running? In pure .NET we can subscribe to events of the Process class, can I do the same in PowerShell?
推荐答案
当然可以!您需要的是 对象事件:
Sure you can! What you need is an Object Events:
对象事件是一个 .Net 对象,它不仅具有对象中通常的属性和方法,而且还有另一个名为事件的成员strong>,您可以使用 Register-ObjectEvent 注册订阅
这里是 PowerShell 论坛.它将异步输出来自 ping 命令的数据(至少从脚本的角度来看):
Here is slightly modified example from the the PowerShell forums. It will output data from the ping command asynchronously (at least from the script point of view):
# Setup stdin\stdout redirection
$StartInfo = New-Object System.Diagnostics.ProcessStartInfo -Property @{
FileName = 'ping.exe'
Arguments = '-t 127.0.0.1'
UseShellExecute = $false
RedirectStandardOutput = $true
RedirectStandardError = $true
}
# Create new process
$Process = New-Object System.Diagnostics.Process
# Assign previously created StartInfo properties
$Process.StartInfo = $StartInfo
# Register Object Events for stdin\stdout reading
$OutEvent = Register-ObjectEvent -Action {
Write-Host $Event.SourceEventArgs.Data
} -InputObject $Process -EventName OutputDataReceived
$ErrEvent = Register-ObjectEvent -Action {
Write-Host $Event.SourceEventArgs.Data
} -InputObject $Process -EventName ErrorDataReceived
# Start process
[void]$Process.Start()
# Begin reading stdin\stdout
$Process.BeginOutputReadLine()
$Process.BeginErrorReadLine()
# Do something else while events are firing
do
{
Write-Host 'Still alive!' -ForegroundColor Green
Start-Sleep -Seconds 1
}
while (!$Process.HasExited)
# Unregister events
$OutEvent.Name, $ErrEvent.Name |
ForEach-Object {Unregister-Event -SourceIdentifier $_}
这篇关于PowerShell,流处理输出和运行外部进程时的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!