我正在尝试重定向我的流程(用VB.NET编写)的standard
和error
的输出,其中我正在执行连续命令。这是一个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
这两个命令在命令提示符下都很好用。但是,当尝试重定向代码中的输出时,执行StreamReader.ReadLine
时,只有命令号1起作用,而第二个命令卡住。
请注意,我知道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
答案 0 :(得分:1)
这全是一个tshark
问题,从没有一个VB.Net问题。
正如Mr.Kurt Knochner
在回答问题How to pipe tshark output in realtime?时提到的:
tshark输出已缓冲。如果需要,请使用
tshark
选项-l tshark在每个数据包之后刷新STDOUT。
并参考tshark
here的文档:
-l在打印每个数据包的信息后刷新标准输出。
因此,为了使其正常运行,我在命令行中添加了--print
选项和-l
,现在它就像一个超级按钮一样工作,现在看起来像这样:
tshark --print -l -i 10 -w ./sample.pcap -E separator=/t -T fields -e frame.number -e dns.qry.name src port 53
这是我的最终代码版本:
Public Class Form1
Dim outputQueue As New Queue(Of String)
Dim captureAdapterID As Integer = 0
Dim oProcess As Process
Private Sub Button1_Click(sender1 As Object, e1 As EventArgs) Handles Button1.Click
Button1.Enabled = False
Button2.Enabled = True
captureAdapterID = (ComboBox1.SelectedIndex + 1)
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender1 As Object, e1 As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Try
oProcess = New Process()
Dim oStartInfo As New ProcessStartInfo("C:\Program Files\Wireshark\tshark.exe", " --print -l -i " & captureAdapterID & " -w ./sample.pcap -E separator=/t -T fields -e frame.number -e dns.qry.name src port 53")
oStartInfo.WorkingDirectory = New Uri(System.Windows.Forms.Application.StartupPath).LocalPath
oStartInfo.UseShellExecute = False
oStartInfo.RedirectStandardOutput = True
oStartInfo.RedirectStandardError = True
oStartInfo.CreateNoWindow = True
oStartInfo.WindowStyle = ProcessWindowStyle.Hidden
oProcess.StartInfo = oStartInfo
If oProcess.Start() Then
appendOutput("Capturing on device: " & captureAdapterID & " started.")
Dim sOutput As String
Using oStreamReader As System.IO.StreamReader = oProcess.StandardOutput
sOutput = oStreamReader.ReadLine
While Not sOutput Is Nothing
appendOutput(sOutput)
sOutput = oStreamReader.ReadLine
End While
End Using
Using oStreamReader As System.IO.StreamReader = oProcess.StandardError
sOutput = oStreamReader.ReadLine
While Not sOutput Is Nothing
appendOutput(sOutput)
sOutput = oStreamReader.ReadLine
End While
End Using
MsgBox("finished")
Else
MsgBox("Error starting the process")
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
BackgroundWorker1.ReportProgress(10)
End Try
End Sub
Private Sub appendOutput(sOutput As String)
outputQueue.Enqueue(sOutput)
BackgroundWorker1.ReportProgress(10)
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Dim i As Integer = 0
For i = 0 To outputQueue.Count - 1 Step 1
RichTextBox1.AppendText(outputQueue.Dequeue & vbNewLine)
Next
RichTextBox1.ScrollToCaret()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
BackgroundWorker1.CancelAsync()
oProcess.Kill()
Button1.Enabled = True
Button2.Enabled = False
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
Dim process As New Process()
Dim oStartInfo As New ProcessStartInfo("C:\Program Files\Wireshark\tshark.exe", " -D")
oStartInfo.WorkingDirectory = New Uri(System.Windows.Forms.Application.StartupPath).LocalPath
oStartInfo.UseShellExecute = False
oStartInfo.RedirectStandardOutput = True
oStartInfo.RedirectStandardError = True
oStartInfo.CreateNoWindow = True
oStartInfo.WindowStyle = ProcessWindowStyle.Hidden
process.StartInfo = oStartInfo
If process.Start() Then
Dim sOutput As String
Using oStreamReader As System.IO.StreamReader = process.StandardOutput
sOutput = oStreamReader.ReadToEnd
If Not sOutput Is Nothing Then
ComboBox1.Items.AddRange(sOutput.Trim.Split(vbNewLine))
Try
ComboBox1.SelectedIndex = 0
Catch ex As Exception
End Try
End If
End Using
Else
MsgBox("Error starting the get adapter process failed")
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class