【发布时间】:2019-05-19 15:39:51
【问题描述】:
我正在尝试重定向我的进程的standard 和error 输出(用VB.NET 编写),我正在执行一个连续命令。它是一个tshark 命令(Wireshark 的命令行工具),在运行时捕获网络流量。我尝试了以下两个命令:
-i 5 -B 1 -w /sample.pcap --print -Tfields -e frame.number -e ip.addr -e tcp -e _ws.col.Info -E separator=/t-i 10 -T fields -e dns.qry.name src port 53
这两个命令在命令提示符下都很好用。但是,当尝试在代码中重定向输出时,只有第 1 条命令有效,而第二条命令在执行 StreamReader.ReadLine 时卡住。
请注意,我知道ReadLine 等待流读取新行,其中上述两个命令都会为每个捕获的数据包生成新的输出行。我也尝试过使用Read 和ReadBlock(关于代码中需要的更改),但没有一个对第二个命令有效。
这是我的代码:
Public Class Form1
Dim output As String
Dim oProcess As New Process()
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
Dim oStartInfo As New ProcessStartInfo("C:\Program Files\Wireshark\tshark.exe", "-i 10 -T fields -e dns.qry.name src port 53")
oStartInfo.UseShellExecute = False
oStartInfo.RedirectStandardOutput = True
oStartInfo.RedirectStandardError = True
oStartInfo.CreateNoWindow = True
oStartInfo.WindowStyle = ProcessWindowStyle.Hidden
oProcess.StartInfo = oStartInfo
Catch ex As Exception
MsgBox(ex)
End Try
BackgroundWorker1.RunWorkerAsync()
Button1.Enabled = False
Button2.Enabled = True
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Try
Threading.Thread.Sleep(2000)
If oProcess.Start() Then
Dim sOutput As String
Using oStreamReader As System.IO.StreamReader = oProcess.StandardOutput
sOutput = oStreamReader.ReadLine
While Not sOutput Is Nothing
output = sOutput & vbNewLine
BackgroundWorker1.ReportProgress(10)
sOutput = sOutput + vbNewLine + oStreamReader.ReadLine
End While
End Using
Using oStreamReader As System.IO.StreamReader = oProcess.StandardError
sOutput = oStreamReader.ReadLine
While Not sOutput Is Nothing
output = sOutput & vbNewLine
BackgroundWorker1.ReportProgress(10)
sOutput = sOutput + vbNewLine + oStreamReader.ReadLine
End While
End Using
Else
MsgBox("Error starting the process")
End If
Catch ex As Exception
MsgBox(ex)
End Try
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
TextBox1.Text = output
TextBox1.Select(0, 0)
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
BackgroundWorker1.CancelAsync()
Button1.Enabled = True
Button2.Enabled = False
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
End Class
【问题讨论】:
-
您不需要 BackgroundWorker。将异步(事件驱动)
BeginOutputReadLine()和BeginErrorReadLine()与Exited事件结合使用。示例代码here(输出到那里的 RichTextBox。当然,您可以更新任何其他控件)。 -
@Jimi 谢谢,我现在尝试了这个,它读取命令的前 3 行(这些行提示使用该捕获开始)并停止读取其他任何内容,我检查了
Exited事件是否在没有被解雇的地方被解雇。我开始认为tshark可能正在使用另一个输出编写器来打印数据包。你觉得呢? -
试试这个作为参数:
"-i 10 -j ""http tcp ip"" -P -V"。您应该会看到大量信息流。 -
然后试试:
"-i 10 -T fields -e frame.number -e ip.addr -e udp -e _ws.col.Info -j ""http tcp ip"" -P -V"。之后缩小范围。您应该偶尔会看到一些信息。 -
@Jimi 两个命令的工作方式和你提到的完全一样,但是我的(命令号 2)仍然没有打印,有什么想法吗?