【问题标题】:Asynchronous redirect StandardOutput and StandardError异步重定向 StandardOutput 和 StandardError
【发布时间】:2014-07-11 13:03:47
【问题描述】:

我正在尝试重定向长流程的标准输出和标准错误。这是一个可能需要 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 (x86).." -a -k -R -r1 -p29000 vob_db" E:\backup2\db db_VISTA 版本 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),共1条记录 -------------------------------------------------- ---------------------- 处理数据文件: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%

请指教。谢谢!

【问题讨论】:

    标签: c# .net vb.net windows cmd


    【解决方案1】:

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

    cmd /c "commandToRun 2>&1"
    

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

    但是,显然您不会在 stderr 上检索任何数据。

    【讨论】:

    • 谢谢。我在这里发布之前尝试过(它没有像你说的那样在 stderr 上检索数据)
    【解决方案2】:

    不同命令背后的原因是,在控制台中,确实将单个输出流分配给“标准输出”和“错误输出”,而当您的应用程序调用时,有两个流不同步,因此您的 SortOutputHandler 事件以任意顺序调用(如果在写入输出或刷新之间有极长的暂停,则可能会偶然正确排序)。

    唯一的解决方案是确保只有一个流。问题是我不知道允许使用 ProcessStartInfo 类的解决方案。 一种可能性是在“暂停”模式下启动进程,然后将其标准错误句柄强制重定向到输出句柄,然后让它运行(就像cmd.exe 所做的那样)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多