CMD在仍在运行流程时输入和输出

时间:2017-11-05 19:22:01

标签: .net vb.net cmd

过去三个小时我一直在寻找一个解决方案,但是只有在流程完成后才找到输出CMD内容的解决方案,而不是在它仍在运行时。

我的代码目前如下:

Public Class main_form
 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim process_cmd As ProcessStartInfo = New ProcessStartInfo("cmd.exe")
    Dim process_obj As Process
    process_cmd.CreateNoWindow = True
    process_cmd.UseShellExecute = False
    process_cmd.RedirectStandardInput = True
    process_cmd.RedirectStandardOutput = True
    process_obj = Process.Start(process_cmd)
    process_obj.StandardInput.WriteLine("my command")
    process_obj.StandardInput.Close()
    RichTextBox1.Text = process_obj.StandardOutput.ReadToEnd
    process_obj.StandardOutput.Close()
 End Sub
End Class

现在这段代码运行正常但是只有在CMD中的进程完成后才会输出到Richtextbox。我希望Richtextbox实时显示CMD窗口的内容,以及在它仍在运行时接受其他命令(例如当前进程的状态)的过程,就好像Richtextbox本身就是CMD窗口一样输出(基本上镜像CMD窗口)。

我想这样做,然后我可以使用我的应用程序操作输出的内容,然后基于此输入更多参数到CMD过程。 (例如,运行服务器并在某些参数仍在运行时更改它们。)

修改

我几乎能够通过使用重定向标准输出完成我的任务,这是我不知道的东西,直到另一个用户引起我的注意。

以下是我的新代码:

Public Class main_form
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim p As New Process()
    p.StartInfo.FileName = "mycmdexecutable"
    p.StartInfo.Arguments = ""
    p.StartInfo.WorkingDirectory = ""
    p.StartInfo.RedirectStandardError = True
    p.StartInfo.RedirectStandardOutput = True
    p.EnableRaisingEvents = True
    p.StartInfo.UseShellExecute = False
    Application.DoEvents()
    AddHandler p.ErrorDataReceived, AddressOf p_OutputDataReceived
    AddHandler p.OutputDataReceived, AddressOf p_OutputDataReceived
    p.Start()
    p.BeginErrorReadLine()
    p.BeginOutputReadLine()

End Sub

Delegate Sub UpdateTextBoxDelg(text As String)
Public myDelegate As UpdateTextBoxDelg = New UpdateTextBoxDelg(AddressOf UpdateTextBox)
Public Sub UpdateTextBox(text As String)
    RichTextBox1.Text += text & Environment.NewLine
    RichTextBox1.SelectionStart = RichTextBox1.Text.Length
    RichTextBox1.ScrollToCaret()
End Sub

Public Sub p_OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
    If Me.InvokeRequired = True Then
        Me.Invoke(myDelegate, e.Data)
    Else
        UpdateTextBox(e.Data)
    End If
End Sub

此代码适用于将CMD输出显示到我拥有的richtextbox。然而,出现了两个新问题。

  • 我现在无法将数据输入到我正在运行的流程中,我完全不知道从哪里开始,我在网上找到的现有示例太复杂了,我无法理解。

  • 我在richtextbox中的输出包括CMD窗口中没有的一些无效字符和字符(例如[0m'])。我最初认为这是richtextbox的编码错误,但似乎并非如此,我不知道如何进一步发展。

再次感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

使用ProcessWriter将您的输入发送到您的流程

Public Class main_form

Private ProcessWriter As StreamWriter 'add this to global declare

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim p As New Process()
    p.StartInfo.FileName = "mycmdexecutable"
    p.StartInfo.Arguments = ""
    p.StartInfo.WorkingDirectory = ""
    p.StartInfo.RedirectStandardError = True
    p.StartInfo.RedirectStandardOutput = True
    p.StartInfo.RedirectStandardInput = True  'added this to redirect your input
    p.EnableRaisingEvents = True
    p.StartInfo.UseShellExecute = False
    Application.DoEvents()
    AddHandler p.ErrorDataReceived, AddressOf p_OutputDataReceived
    AddHandler p.OutputDataReceived, AddressOf p_OutputDataReceived
    p.Start()
    ProcessWriter = p.StandardInput
    p.BeginErrorReadLine()
    p.BeginOutputReadLine()

End Sub