异步重定向StandardOutput和StandardError

本文关键字:StandardError StandardOutput 重定向 异步 | 更新日期: 2023-09-27 18:12:41

我试图重定向一个长过程的标准输出和标准错误。这是一个可能需要40分钟才能完成处理的Exe文件。

问题是,如果我从命令行(cmd)运行EXE, stdout和stderr以某种顺序显示在控制台上,这是我希望它从我的应用程序重定向的顺序,但它不起作用。我在使用以下函数的时候改变了顺序,找不到原因是什么。我希望你能给我一些建议。

这是我使用的代码:

Public numOutputLines As Integer = 0
Public sortOutput As StringBuilder = Nothing

Public Function ProcessTask3New(ByVal ExeName As String, ByVal arguments As String, ByRef stdout As String, ByRef stderr As String, ByRef ExitCode As Integer, _
                                  Optional ByVal Filename As String = "", Optional ByVal IsDeleteTempLogFiles As Boolean = False) As Boolean
        ' This fucntion executes cmd commands and arguments,
        ' Function returns standard output and startdard error. stderr contains data if error was generated 

        Try
            ProcessTask3New = True
            Dim p As Process
            Dim psi As ProcessStartInfo

            Dim currentTime As System.DateTime
            currentTime = System.DateTime.Now
            If Filename <> "" Then Filename = Replace(Filename & ".", "'", "")
            Dim tmpStdoutFilename As String = System.IO.Path.GetTempPath & "stdout." & Filename & currentTime.Ticks.ToString()
            Dim tmpStderrFilename As String = System.IO.Path.GetTempPath & "stderr." & Filename & currentTime.Ticks.ToString()

            netOutput = New StringBuilder
            p = New Process
            psi = p.StartInfo
            psi.Arguments = psi.Arguments.Replace("/C " & Chr(34), "/C " & Chr(34) & Chr(34))
            psi.FileName = ExeName
            psi.UseShellExecute = False
            psi.WindowStyle = ProcessWindowStyle.Minimized
            ' Redirect the standard output of the sort command.   
            ' Read the stream asynchronously using an event handler.
            psi.RedirectStandardOutput = True
            psi.RedirectStandardError = True
            psi.CreateNoWindow = True
            sortOutput = New StringBuilder()
            ' Set our event handler to asynchronously read the sort output. 
            AddHandler p.OutputDataReceived, _
                       AddressOf SortOutputHandler

            AddHandler p.ErrorDataReceived, AddressOf SortOutputHandler


            If IsDebug Then Write2Log("ProcessTask3New: " + psi.FileName.ToString + " " + psi.Arguments.ToString)
            Try
                Write2Log(My.Computer.FileSystem.CurrentDirectory)
                p.Start()
            Catch w As System.ComponentModel.Win32Exception
                Write2Log("ProcessTask3New: " & w.Message)
                Write2Log("ProcessTask3New: " & w.ErrorCode.ToString())
                Write2Log("ProcessTask3New: " & w.NativeErrorCode.ToString())
                Write2Log("ProcessTask3New: " & w.StackTrace)
                Write2Log("ProcessTask3New: " & w.Source)
                Dim e As New Exception()
                e = w.GetBaseException()
                Write2Log("ProcessTask3New: " & e.Message)
            End Try


            ' Start the asynchronous read of the sort output stream.
            p.BeginOutputReadLine()
            p.BeginErrorReadLine()
            p.WaitForExit()
            ExitCode = p.ExitCode
            p.Close()

            netOutput = Nothing
        Catch ex As Exception
            Write2Log("error at ProcessTask3New function: " & ex.ToString & " : " + ex.StackTrace)
        End Try
    End Function
    Private Sub SortOutputHandler(ByVal sendingProcess As Object, _
       ByVal outLine As DataReceivedEventArgs)
        ' Collect the sort command output. 
        If Not String.IsNullOrEmpty(outLine.Data) Then
            numOutputLines += 1
             Add the text to the collected output.
            sortOutput.Append(Environment.NewLine + "[" _
                         + numOutputLines.ToString() + "] - " _
                         + outLine.Data)
        End If
    End Sub

现在输出这是我从cmd窗口运行它时的样子(这很好):


处理密钥文件:vob_db.k01(1),共291个节点

处理删除链:删除链上有1个节点。处理节点:+ + + + + + + + + 10 %+++++++++ 20 %+++++++++ 30 %+++++++++ 40 %+++++++++ 50 %+++++++++ 60 %+++++++++ 70年 %+++++++++ 80年 %+++++++++ 90年 %+++++++++

100%

处理密钥文件:vob_db.k02(2),共1246个节点

处理删除链:删除链上有2个节点。处理节点:+ + + + + + + + + 10 %+++++++++ 20 %+++++++++ 30 %+++++++++ 40 %+++++++++ 50 %+++++++++ 60 %+++++++++ 70年 %+++++++++ 80年 %+++++++++ 90年 %+++++++++

100%

处理密钥文件:vob_db.k03(5),共1个节点

处理删除链:删除链上有0个节点。处理节点:

100%

处理密钥文件:vob_db.k04(6),共277个节点

处理删除链:删除链上有7个节点。处理节点:+ + + + + + + + + 10 %+++++++++ 20 %+++++++++ 30 %+++++++++ 40 %+++++++++ 50 %+++++++++ 60 %+++++++++ 70年 %+++++++++ 80年 %+++++++++ 90年 %+++++++++

100%

(像这样的行来自stderr.)

+++++++++ 10 %+++++++++ 20 %+++++++++ 30 %+++++++++ 40 %+++++++++ 50 %+++++++++ 60% + +

当我从我的应用程序中运行它时(这是坏的):

ProcessTask3New: cmd.exe/C "C:'Program Files . C(x86)…"-a -k -R -r1-p29000 vob_db" E:'backup2'db db_VISTA Version 3.20数据库一致性检查实用程序版权所有(C) 1985-1990 Raima公司版权所有------------------------------------------------------------------------ 处理密钥文件:vob_db.k01(1),共有291个节点------------------------------------------------------------------------ 处理密钥文件:vob_db.k02(2),共有1246个节点------------------------------------------------------------------------ 处理密钥文件:vob_db.k03(5), 1个节点------------------------------------------------------------------------ 处理密钥文件:vob_db.k04(6),共有277个节点------------------------------------------------------------------------ 处理数据文件:vob_db.d01(0),共有7107条记录------------------------------------------------------------------------ 处理数据文件:vob_db.d02(3),共有20516条记录------------------------------------------------------------------------ 处理数据文件:vob_db.d03(4),共记录------------------------------------------------------------------------ 处理数据文件:vob_db.d04(7),共0记录------------------------------------------------------------------------ 处理数据文件:vob_db.d05(8),总共39938条记录处理删除链:删除链上有1个节点。在0中遇到0个错误记录/节点+ + + + + + + + + 10 %+++++++++ 20 %+++++++++ 30 %+++++++++ 40 %+++++++++ 50 %+++++++++ 60 %+++++++++ 70年 %+++++++++ 80年 %+++++++++ 90年 %+++++++++ 100%处理删除链:2节点删除链。处理节点:+ + + + + + + + + 10 %+++++++++ 20 %+++++++++ 30 %+++++++++ 40 %+++++++++ 50 %+++++++++ 60 %+++++++++ 70年 %+++++++++ 80年 %+++++++++ 90年 %+++++++++ 100%处理删除链:0节点删除链。处理节点:

100%

请建议。谢谢你!

异步重定向StandardOutput和StandardError

您可以选择"混合"标准输出和标准错误,将标准错误重定向到标准输出

cmd /c "commandToRun 2>&1"

这里我们要求cmd执行一些命令并将流2 (stderr)的输出重定向到流1 (stdout)。

不同顺序背后的原因是,当在控制台时,单个输出流确实被分配给"标准输出"answers"错误输出",并且当您的应用程序调用时,有两个不同步的流,因此您的SortOutputHandler事件以任何顺序调用(如果在写入输出或刷新之间有极长的暂停,它可能会得到正确的顺序)。

唯一的解决方案,你必须得到这个很好的排序是确保有一个单一的流。问题是,我不知道一个解决方案允许使用ProcessStartInfo类。一种可能性是以"暂停"模式启动进程,然后强制将其标准错误句柄重定向到输出句柄,然后让它运行(如cmd.exe所做的)