簡體   English   中英

VB.Net以另一種形式發送啟動過程的輸出和輸入

[英]VB.Net Send output and input of process started in another form

我有2種表單,MainForm和RCONForm。 我想做的是在程序啟動時啟動一個過程,在這種情況下,我選擇了cmd.exe,它可以正常工作。

問題是我希望能夠使用2個文本框讀取輸出並將輸入從另一種形式發送到流程中。

問題是我無法從該進程中讀取任何內容,也無法向該進程發送任何輸入。

我的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

我一直在考慮使用線程,也許可以解決問題,還是有更簡單的方法?

您正在大量使用默認表單實例。 如果可能,您應該避免這種情況。 這是一種跟蹤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

更新所有訪問RCONFormmyRCONForm中的MainForm

另外,這還有一點缺陷,您可以在其中檢查是否需要在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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM