Перенаправление вывода процесса в richtextbox
Я пытаюсь перенаправить вывод стороннего инструмента командной строки, который запускается моим приложением. Я вывожу в расширенное текстовое поле. Это работает успешно, за одним исключением.
Когда я тестирую с помощью команды ping, мой вывод не отформатирован правильно. одна строка добавляется к предыдущей. Когда я пытаюсь поставить VbNewLine
там или VbCrLf
или Environment.NewLine
это ставит дополнительную пустую строку.
Я получаю этот вывод:
Pinging 8.8.8.8 with 32 bytes of data:
Reply from 8.8.8.8: bytes=32 time=29ms TTL=44
Reply from 8.8.8.8: bytes=32 time=29ms TTL=44
Reply from 8.8.8.8: bytes=32 time=30ms TTL=44
Reply from 8.8.8.8: bytes=32 time=29ms TTL=44
Ping statistics for 8.8.8.8:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 29ms, Maximum = 30ms, Average = 29ms
Я хочу получить (как это в окне CMD):
Pinging 8.8.8.8 with 32 bytes of data:
Reply from 8.8.8.8: bytes=32 time=31ms TTL=44
Reply from 8.8.8.8: bytes=32 time=29ms TTL=44
Reply from 8.8.8.8: bytes=32 time=29ms TTL=44
Reply from 8.8.8.8: bytes=32 time=29ms TTL=44
Ping statistics for 8.8.8.8:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 29ms, Maximum = 31ms, Average = 29ms
Я уверен, что это очень просто, но не могу понять это.
Вот код, который я использую.
Private Sub StartProcess()
Dim Proc = New Process()
Proc.StartInfo.FileName = "ping"
Proc.StartInfo.Arguments = "8.8.8.8"
Proc.StartInfo.RedirectStandardOutput = True
Proc.StartInfo.RedirectStandardError = True
Proc.EnableRaisingEvents = True
Application.DoEvents()
Proc.StartInfo.CreateNoWindow = True
Proc.StartInfo.UseShellExecute = False
AddHandler Proc.ErrorDataReceived, AddressOf proc_OutputDataReceived
AddHandler Proc.OutputDataReceived, AddressOf proc_OutputDataReceived
Proc.Start()
Proc.BeginErrorReadLine()
Proc.BeginOutputReadLine()
'Proc.WaitForExit()
End Sub
Delegate Sub UpdateTextBoxDelg(ByVal text As String)
Public myDelegate As UpdateTextBoxDelg = New UpdateTextBoxDelg(AddressOf UpdateTextBox)
Public Sub UpdateTextBox(ByVal text As String)
box_output.AppendText(text)
End Sub
Public Sub proc_OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
On Error Resume Next
If Me.InvokeRequired = True Then
Me.Invoke(myDelegate, e.Data)
Else
UpdateTextBox(e.Data)
End If
End Sub
2 ответа
Немного ошеломил, взял меня немного. Я заметил, что e.Data может быть ничем, никогда не видел этого раньше. Утилиты сети, ну, особенные, Беркли - необычное место на планете Земля.
Вы должны добавить конец строки самостоятельно. Использование InvokeRequired бессмысленно, оно всегда для события OutputDataReceived. Эта версия работала нормально:
Public Sub proc_OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
If e.Data IsNot Nothing Then Me.Invoke(myDelegate, e.Data + vbCrLf)
End Sub
Пожалуйста, используйте взамен класс System.Net.NetworkInformation.Ping. Он не так подвержен влиянию рекреационных химических веществ.
Это работает нормально для меня; просто измените ваш код следующим образом:
Public Sub UpdateTextBox(ByVal text As String)
RichTextBox2.AppendText(text & System.Environment.NewLine)
End Sub