Перенаправление вывода процесса в 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

Скриншот

Другие вопросы по тегам