VB.Net发送输出和进程的输入以另一种形式启动

时间:2017-10-06 17:24:17

标签: vb.net

我有2个表单,MainForm和RCONForm。 我想要做的是在程序启动时启动一个进程,在这种情况下,我选择了cmd.exe并且它可以工作。

问题是我希望能够读取输出并使用2个文本框从另一个表单向进程发送输入。

问题在于我无法从过程中读取任何内容,也无法向其发送任何输入。

My MainForm:

Public Class MainForm

#Region "Import Function"

    Dim Functions As New Functions
    Friend WithEvents RCON As Process

#End Region

    Friend Sub AppendOutputText(ByVal text As String)
        If RCONForm.RCONLogText.InvokeRequired Then
            Dim myDelegate As New RCONForm.AppendOutputTextDelegate(AddressOf AppendOutputText)
            Me.Invoke(myDelegate, text)
        Else
            RCONForm.RCONLogText.AppendText(text)
        End If
    End Sub

    Private Sub MainForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        RCON = New Process
        With RCON.StartInfo
            .FileName = "C:\Windows\system32\CMD.exe"
            .UseShellExecute = False
            .CreateNoWindow = True
            .RedirectStandardInput = True
            .RedirectStandardOutput = True
            .RedirectStandardError = True
        End With
        RCON.Start()
        RCON.BeginErrorReadLine()
        RCON.BeginOutputReadLine()
        AppendOutputText("RCON Started at: " & RCON.StartTime.ToString)
    End Sub

    Private Sub RCONButton_Click(sender As Object, e As EventArgs) Handles RCONButton.Click
        Functions.KillOldForm()
        Functions.SpawnForm(Of RCONForm)()
    End Sub

    Private Sub ExitButton_Click(sender As Object, e As EventArgs) Handles ExitButton.Click
        Application.Exit()
    End Sub

    Private Sub ServerButton_Click(sender As Object, e As EventArgs) Handles ServerButton.Click
        Functions.KillOldForm()
        Functions.SpawnForm(Of ServerForm)()
    End Sub
End Class

我的RCONForm:

Public Class RCONForm

    Friend Delegate Sub AppendOutputTextDelegate(ByVal text As String)
    Friend WithEvents RCON As Process = MainForm.RCON

    Friend Sub RCON_ErrorDataReceived(ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs) Handles RCON.ErrorDataReceived
        MainForm.AppendOutputText(vbCrLf & "Error: " & e.Data)
    End Sub

    Friend Sub RCON_OutputDataReceived(ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs) Handles RCON.OutputDataReceived
        MainForm.AppendOutputText(vbCrLf & e.Data)
    End Sub

    Friend Sub RCONCommandText_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles RCONCommandText.KeyPress
        If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then
            MainForm.RCON.StandardInput.WriteLine(RCONCommandText.Text)
            MainForm.RCON.StandardInput.Flush()
            RCONCommandText.Text = ""
            e.Handled = True
        End If
    End Sub

    Friend Sub RCONForm_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        MainForm.RCON.StandardInput.WriteLine("EXIT") 'send an EXIT command to the Command Prompt
        MainForm.RCON.StandardInput.Flush()
        MainForm.RCON.Close()
    End Sub

    Private Sub RCONForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub
End Class

我的职能:

#Region "Kill Old Forms"

    Function KillOldForm()
        While MainForm.SpawnPanel.Controls.Count > 0
            MainForm.SpawnPanel.Controls(0).Dispose()
        End While
        Return Nothing
    End Function

#End Region

#Region "Spawn Form"

    Function SpawnForm(Of T As {New, Form})() As T
        Dim spawn As New T() With {.TopLevel = False, .AutoSize = False}
        Try
            spawn.Dock = DockStyle.Fill
            MainForm.SpawnPanel.Controls.Add(spawn)
            spawn.Show()
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
        Return Nothing
    End Function

#End Region

我一直在考虑使用线程,也许这可以解决问题,还是有更简单的方法?

1 个答案:

答案 0 :(得分:0)

您正在大量使用默认表单实例。你应该尽可能避免这种情况。这是一种在MainForm

中跟踪RCONForm的正确实例的方法
Private myRCONForm As RCONForm

Private Sub RCONButton_Click(sender As Object, e As EventArgs) Handles RCONButton.Click
    Functions.KillOldForm()
    myRCONForm = Functions.SpawnForm(Of RCONForm)()
End Sub

现在SpawnForm是一个函数,它将返回表单,以便您可以保留对它的引用

Public Function SpawnForm(Of T As {New, Form})() As T
    Dim myForm = New T()
    ' add myForm to the appropriate Panel or whatever
    Return myForm
End Function

使用MainForm

中的RCONForm更新对myRCONForm的所有访问权限

此外,这有点缺陷,您可以在RCONForm.RCONLogText检查是否需要调用,然后在Me上调用。它可以简化

' old with default form instance

Friend Sub AppendOutputText(ByVal text As String)
    If RCONForm.RCONLogText.InvokeRequired Then
        Dim myDelegate As New RCONForm.AppendOutputTextDelegate(AddressOf AppendOutputText)
        Me.Invoke(myDelegate, text)

    Else
        RCONForm.RCONLogText.AppendText(text)
    End If
End Sub

' new, with instance reference plus simplified invocation

Friend Sub AppendOutputText(text As String)
    If myRCONForm.RCONLogText.InvokeRequired Then
        myRCONForm.RCONLogText.Invoke(New Action(Of String)(AddressOf AppendOutputText), text)
    Else
        myRCONForm.RCONLogText.AppendText(text)
    End If
End Sub