1

Я пытаюсь перенаправить вывод инструмента командной строки третьей стороны, который запускается моим приложением. Я выводю в богатое текстовое поле. Это работает успешно, за одним исключением.Перенаправление вывода процесса в 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 
+0

Я удалил ответ, потому что не может решить вашу проблему, если я даже не могу понять, в чем проблема. Я предлагаю вам сделать правильную отладку (по очереди), чтобы увидеть, что происходит каждый раз, чтобы прийти с помощью специального решения, избегая дублирования строк. Другим вариантом может быть глобальная замена дублированных строк новой строки после заполнения RTB; но опять же я не знаю точных условий (пробел между дублированными новыми строками?) и, следовательно, ничего не может предложить. Эта проблема звучит неразрешимо с моей позиции, но довольно легко от вас. – varocarbas

+0

Слишком плохо. Хотя это был не ответ, я бы назвал его полезным, потому что это было так. В любом случае, спасибо за ваши усилия. – NapkinBob

+0

Нет ничего сложного. Если я не считаю, что мой ответ действительно затрагивает проблему, в чем смысл ее сохранения? Я понятия не имел, почему ваш код выводит эти результаты так ... Было бы странно, если бы люди искали помощь с той же проблемой. Спасибо за ваше намерение. – varocarbas

ответ

3

Немного о навороте, потребовалось некоторое время. Я заметил, что e.Data может быть Ничем, никогда не видел этого раньше. Сетевые утилиты, erm, специальные, Berkeley - необычное место на планете Земля.

Вам нужно добавить конец линии. Использование 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. Реанимационные химические вещества не так сильно затронуты.

+0

В ретроспективе, возможно, использование пинга было плохим выбором. Я только использовал это, чтобы проверить, пока не построил остальную часть моего кода. (Мне нужно создать пользовательскую строку аргументов, чтобы перейти к процессу). Пинг был первым, что я подумал о том, что ему нужна команда и аргументы (буквально первое) и выведет несколько строк вывода. Я не считал, что проблема с ping была проблемой. Думаю, я закончу код и посмотрю, как он работает с реальным инструментом, который мне нужно использовать. Я просто подумал, что это должно работать теоретически. Я попробую, что вы предлагаете, чтобы упростить вызов. – NapkinBob

0

Его работая отлично для меня; просто изменить код следующим образом:

Public Sub UpdateTextBox(ByVal text As String) 
    RichTextBox2.AppendText(text & System.Environment.NewLine) 
End Sub 

ScreenShot

Смежные вопросы