控制台应用程序不想读取标准输入

时间:2013-09-22 19:35:33

标签: vb.net io stream

我正在编写一个应用程序来管理其他控制台应用程序(游戏服务器 - jampded.exe

当它在控​​制台中运行时,它会毫无问题地写入数据并读取命令。

在我的应用程序中,我将标准I / O重定向到StreamWriter和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

当我按Button2时应该从我的文本框中写入STD / I文本时,jampded.exe表现得像是没有写过。此外,输出在启动时运行良好,之后在缓冲区中有大量数据时很少添加新行。

我做错了什么,或者是应用程序的错?

1 个答案:

答案 0 :(得分:2)

对于标准输入问题:

您确定您正在启动的应用程序是从标准输入读取数据(而不是捕获键盘事件或其他内容)吗?要对此进行测试,请将您尝试发送到应用程序的一些文本放在文本文件中(例如,命名为commands.txt)。然后从命令提示符将其发送到应用程序,如下所示:

type commands.txt | jampded.exe

如果该应用程序读取这些命令,那么它确实是从标准输入读取的。如果不是,则重定向标准输入不会帮助您获取该应用程序的数据。

对于标准输出问题:

我建议不要启动自己的线程来处理来自其他应用程序的数据,而是建议这样做:

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

Invoke调用是必需的,因为OutputData可能会在另一个线程上调用,并且所有UI更新都必须在UI线程上进行。

我直接从StandardOutput流中读取数据时遇到了同样的问题。异步读取+事件处理程序组合修复了它。