.net 如何读取控制台缓冲区而不考虑输出的种类?
想象一下,从我的应用程序中,我启动了一个命令行应用程序,它在标准输出上打印这一行:.net 如何读取控制台缓冲区而不考虑输出的种类?,.net,vb.net,winforms,console,buffer,.net,Vb.net,Winforms,Console,Buffer,想象一下,从我的应用程序中,我启动了一个命令行应用程序,它在标准输出上打印这一行: I'm a standard line with special character: # 然后,同一应用程序在错误输出中打印这一行: I'm an error line with special character: @ 因此,无论输出类型是否为: I'm a standard line with special character: # I'm an error line with special cha
I'm a standard line with special character: #
然后,同一应用程序在错误输出中打印这一行:
I'm an error line with special character: @
因此,无论输出类型是否为:
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
附:这个问题是其他未澄清问题的第二部分:
我已经知道如何做这些事情,但人们似乎无法理解我的问题,我想知道这次我对我的问题和我要做的事情给出了更好的解释。你的问题似乎仍然很难解决: 为什么要通过在输出中使用令牌来分离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时,使用以下事件: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
你的问题似乎还是很难回答: 为什么要通过在输出中使用令牌来分离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时,使用以下事件: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
你的问题似乎还是很难回答: 为什么要通过在输出中使用令牌来分离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时,使用以下事件: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
你的问题似乎还是很难回答: 为什么要通过在输出中使用令牌来分离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时,使用以下事件: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
回答你的问题