3

I am writing an application to manage other console application(game server - jampded.exe)

When it's running in console it writes data and reads commands with no problem.

In my application I redirected standard I/O to StreamWriter and StreamReader

Public out As StreamReader
Public input As StreamWriter

Dim p As New Process()
p.StartInfo.FileName = My.Application.Info.DirectoryPath & "\" &
                       TextBox6.Text 'PATH TO JAMPDED.EXE
p.StartInfo.Arguments = TextBox1.Text 'EXTRA PARAMETERS
p.StartInfo.CreateNoWindow = True 
p.StartInfo.RedirectStandardInput = True
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.UseShellExecute = False
p.Start()

input = p.StandardInput
out = p.StandardOutput

Dim thr As Thread = New Thread(AddressOf updatetextbox)
thr.IsBackground = True
thr.Start()

Sub updatetextbox()
  While True
    While Not out.EndOfStream
      RichTextBox1.AppendText(out.ReadLine())
      RichTextBox1.AppendText(vbNewLine)
    End While
  End While
End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) _
                                                       Handles Button2.Click
  input.WriteLine(TextBox4.Text)
  TextBox4.Text = ""
  input.Flush()
End Sub

When I am pressing Button2 that should write to STD/I text from my textbox, jampded.exe acts like it wasn't written. Also Output works well at startup, after that new lines are added rarely when there is a lot data in buffer.

Am I doing something wrong, or is it the application's fault?

Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151
Disa
  • 630
  • 13
  • 42

1 Answers1

2

For the standard input question:

Are you certain that the application you're starting is reading data from standard input (and not trapping keyboard events or something)? To test this, put some text that you're trying to send to the application in a text file (named, for example, commands.txt). Then send it to the application from a command prompt like so:

type commands.txt | jampded.exe

If that application reads those commands, then it is indeed reading from standard input. If it isn't, then redirecting standard input isn't going to help you get data to that application.

For the standard output question:

Instead of launching your own thread to handle the data coming from the other application, I would suggest doing something like this:

AddHandler p.OutputDataReceived, AddressOf OutputData
p.Start()
p.BeginOutputReadLine()

Private Sub AddLineToTextBox(ByVal line As String)
    RichTextBox1.AppendText(e.Data)
    RichTextBox1.AppendText(vbNewLine)
End Sub
Private Delegate Sub AddLineDelegate(ByVal line As String)

Private Sub OutputData(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
    If IsNothing(e.Data) Then Exit Sub
    Dim d As AddLineDelegate
    d = AddressOf AddLineToTextBox
    Invoke(d, e.Data)
End Sub

The Invoke call is required because OutputData may get called on a different thread, and UI updates all have to happen on the UI thread.

I've seen the same issue with data coming in batches when reading from the StandardOutput stream directly. The asynchronous read + event handler combo fixed it.

  • Thank you for your reply +1. Though I found a workaround for STD Input, the standard output even with your code is still much delayed. – Disa Oct 26 '13 at 16:58