想象一下,在我的应用程序中,我启动了一个Commandline应用程序,在该行的标准输出上打印:
I'm a standard line with special character: #
之后,相同的应用程序在错误输出中打印此行:
I'm an error line with special character: @
因此无论输出类型是什么,CMD输出都是这样:
I'm a standard line with special character: #
I'm an error line with special character: @
然后,无论是标准输出还是错误输出,如何同时读取两行? (完整的CMD输出),换句话说,如何读取控制台缓冲区?
澄清:
我不是指如何重定向进程输出以读取标准输入,或错误输出,或两者,我已经知道如何做到这一点,我是什么 意思是读取控制台缓冲区,一个缓冲区,其中(我认为)所有输出(标准/错误/输入)被合并为流中的一个输出而不需要重定向所需的输出,只需读取我可以搜索的缓冲区流对于由应用程序打印的特殊字符,无论打印特殊字符的输出类型如何。
为了更好地理解它,这是一个伪代码:
Private Sub ReadConsoleBuffer()
Dim p As New Process With
{.StartInfo = New ProcessStartInfo With
{.FileName = "MyApp.exe",
.UseShellExecute = False,
.RedirectStandardError = False,
.RedirectStandardOutput = False}} ' There is no need to redirect output because I'm not trying to capture the outputs by myself.
p.Start()
' Process will write an "#" character on the Standard Output,
' And will write an "@" character on the Error Output.
Dim cBuffer As IO.StreamReader = ' ...Function to retrieve the console buffer...
Do Until cBuffer.EndOfStream
Select Case Convert.ToChar(cBuffer.Read)
Case "#"
' "#" character found so we succesfully read the Standard Output from the buffer.
Case "@"
' "@" character found so we succesfully read the Error Output from the buffer.
End Select
cBuffer = ' ...Reassign the buffer data to retrieve new printed lines by the process?...
' really I'm not sure that this would be necessary or not.
Loop
End Sub
我希望您能够注意到我想要做的事情和我不想做的事情之间的区别,上面的代码是我想要做的,而这是正常输出的其他示例重定向是我不想做的事情:
Private Sub ReadConsoleBuffer() Handles MyBase.Shown
Dim p As New Process With
{.StartInfo = New ProcessStartInfo With
{.FileName = "cmd.exe",
.Arguments = "/C Dir /W *.ext not found",
.UseShellExecute = False,
.RedirectStandardError = True,
.RedirectStandardOutput = True}}
p.Start()
Do Until (p.StandardOutput.EndOfStream And p.StandardError.EndOfStream)
RTB_stdOut.AppendText(p.StandardOutput.ReadLine & Environment.NewLine)
RTB_errOut.AppendText(p.StandardError.ReadLine & Environment.NewLine)
Loop
End Sub
PS:这个问题是其他未解决问题的第二部分:
Need an aclaration about the console buffer and console outputs
How to read Console buffer in VBNET?
我已经知道如何做这些事情,但似乎人们无法理解我的问题,我想这次我已经对我的问题以及我想要做的事情做了更好的解释。
答案 0 :(得分:3)
你的问题似乎仍然难以解决:
为什么要在输出中使用标记来分隔stdout和stderr?
如果你想分别读取stdout和stderr的缓冲区,那就去做吧!
创建两个StreamReader,一个用StandardError初始化,另一个用StandardOutput初始化, 单独阅读它们,将它们分开存放瞧!“
既然你坚持要知道怎么做,我会给你一个最后的反问题:
为什么要访问整个"控制台缓冲区"如果你已经可以访问stdout和stderr的单独流,那么稍后用一些特殊字符对stdout / stderr进行排序?
编辑:在测试了相关流程后,我有一个建议:
请勿使用StreamReaders接收子进程中的数据。 尝试以下方式:
创建两种方法:
Private Sub hndStdOutDataReceiver(sender As Object, e As DataReceivedEventArgs)
' Here comes the content from StdOut, do with it what you please
RTB_Output.AppendText(e.Data)
End Sub
Private Sub hndStdErrDataRecevier(sender As Object, e As DataReceivedEventArgs)
' Here comes the content from StdErr, do with it what you please
RTB_Error.AppendText(e.Data)
End Sub
当重定向far进程的StandardOutput / Error而不是创建处理读出的StreamReader时,使用Events:OutputDataReceived和ErrorDataReceived
Dim psi As ProcessStartInfo = New ProcessStartInfo
With psi
.FileName = YOUR_FILENAME
.Arguments = YOUR_ARGUMENTS
.UseShellExecute = False
.RedirectStandardOutput = True
.RedirectStandardError = True
End With
Dim proc as New Process() With { .StartInfo = psi }
' Here comes the crucial difference to your method
AddHandler proc.OutputDataReceived, AddressOf hndStdOutDataReceiver
AddHandler proc.ErrorDataReceived, AddressOf hndStdErrDataRecevier
proc.Start()
proc.BeginOutputReadLine()
proc.BeginErrorReadLine()
proc.WaitForExit()
' wrap up your environment