从PowerShell进程异步记录标准输出

时间:2016-04-20 20:01:17

标签: powershell asynchronous

我需要在PowerShell脚本中启动一个长时间运行的进程,并在生成时将StandardOutput捕获到文件。我目前正在使用异步方法,并在每次触发OutputDataReceived事件时将输出附加到文本文件。以下代码摘录说明:

for ( unsigned ui = 0U ; ui < hashTable.size() ; ++ui )
   loopFreeNode(hashTable[ui]);

此方法的问题是生成的大量输出以及因必须在每个事件中打开和关闭文本文件而导致的延迟(即 Add-Content $ OUTFIL.out $ text 每次触发事件时都会调用)。

$PSI = New-Object System.Diagnostics.ProcessStartInfo
$PSI.CreateNoWindow = $true
$PSI.RedirectStandardOutput = $true
$PSI.RedirectStandardError = $true
$PSI.UseShellExecute = $false
$PSI.FileName = $EXECUTE
$PSI.RedirectStandardInput = $true
$PSI.WorkingDirectory = $PWD
$PSI.EnvironmentVariables["TMP"] = $TMPDIR
$PSI.EnvironmentVariables["TEMP"] = $TMPDIR
$PSI.EnvironmentVariables["TMPDIR"] = $TMPDIR

$PROCESS = New-Object System.Diagnostics.Process
$PROCESS.StartInfo = $PSI

[void]$PROCESS.Start()

# asynchronously listen for OutputDataReceived events on the process
$sb = [scriptblock]::Create("`$text = `$Event.SourceEventArgs.Data; `$OUTFIL = `$Event.MessageData; Add-Content $OUTFIL.out `$text")
$EVENT_OBJ = Register-ObjectEvent -InputObject $PROCESS -EventName OutputDataReceived -Action $sb -MessageData "$OUTFIL.out"

# asynchronously listen for ErrorDataReceived events on the process
$sb2 = [scriptblock]::Create("`$text = `$Event.SourceEventArgs.Data; Write-Host `$text;")
$EVENT_OBJ2 = Register-ObjectEvent -InputObject $PROCESS -EventName ErrorDataReceived -Action $sb2

# begin asynchronous read operations on the redirected StandardOutput
$PROCESS.BeginOutputReadLine();

# begin asynchronous read operations on the redirected StandardError
$PROCESS.BeginErrorReadLine();      

# write the input file contents to standard input
$WRITER = $PROCESS.StandardInput
$READER = [System.IO.File]::OpenText("$IN_FILE")

try
{
    while (($line = $READER.ReadLine()) -ne $null)
    {
        $WRITER.WriteLine($line)
    }
}
finally
{
    $WRITER.close()
    $READER.close()
}

$Process.WaitForExit() | Out-Null

# end asynchronous read operations on the redirected StandardOutput
$PROCESS.CancelOutputRead();

# end asynchronous read operations on the redirected StandardError
$PROCESS.CancelErrorRead();

Unregister-Event -SubscriptionId $EVENT_OBJ.Id

Unregister-Event -SubscriptionId $EVENT_OBJ2.Id

在每种情况下,实际过程将在所有输出数据写入文本文件之前完成几分钟。

有没有更好的方法来做到这一点?将文本附加到文件的更快捷方式?

0 个答案:

没有答案