【问题标题】:Input and output from CMD while it is still running a processCMD 仍在运行进程时的输入和输出
【发布时间】:2017-11-05 19:22:00
【问题描述】:

过去三个小时我一直在寻找解决方案,但只找到了在进程完成后输出 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 的编码错误,但似乎并非如此,我不知道如何进一步发展。

再次感谢您的帮助!

【问题讨论】:

  • 如果将标准输出重定向到文件并从文件中读取会怎样?
  • 感谢您提请我注意。 @PerpetualStudent 我已将重定向标准输出合并到我的代码中。如果您能看看我提供的新信息,我将不胜感激。
  • 不确定这是否可行,但是如果你让你的 cmd 运行一个 bat 文件,然后将更多命令添加到 bat 文件中怎么办。重定向标准输出,重定向标准输入的反向排序。查看此链接:stackoverflow.com/questions/906586/…
  • [0m 是清除所有 ANSI 属性的 ANSI 代码。您可以在播放不良时将其删除。 yourstring.replace("[0m","") ascii-table.com/ansi-escape-sequences.php

标签: .net vb.net cmd


【解决方案1】:

使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 2011-11-05
    • 2013-01-25
    相关资源
    最近更新 更多