我试图重定向长时间进程的stdout和stderr。它可能需要40分钟才能完成处理。
问题是如果我从命令行(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&#34;&#34; C:\ Program Files (86)..&#34; -a -k -R -r1 -p29000 vob_db&#34; 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%+ ++++++++++++++++++++++++++++++++++++++处理节点: +++++++++ 10%+++++++++ 20%+++++++++ 30%+++++++++ 40%++++++ +++ 50%+++++++++ 60%+++++++++ 70%+++++++++ 80%+++++++++ 90%+ +++++++++++++++++++++++++++++++++++++++处理节点: 100%
请指教。谢谢!
答案 0 :(得分:2)
您可以选择&#34;混合&#34; stdout和stderr,将stderr重定向到stdout
cmd /c "commandToRun 2>&1"
这里我们要求cmd
执行一些命令并重定向流2(stderr)将其输出发送到流1(stdout)。
但是,显然你不会在stderr上检索任何数据。
答案 1 :(得分:0)
不同命令背后的原因是,在控制台中,单个输出流确实分配给“标准输出”和“错误输出”,并且当您的应用程序调用时,有两个流不同步,因此您的SortOutputHandler
事件以任何顺序被调用(如果在输出或刷新之间有非常长的暂停,它可能会被正确地命令)。
您必须对此进行良好排序的唯一解决方案是确保存在单个流。问题是我不知道允许使用ProcessStartInfo类的解决方案。
一种可能性是以“暂停”模式启动进程,然后将其标准错误句柄强制重定向到输出句柄,然后让它运行(如cmd.exe
那样)