使用进程发送DOS命令 - 输出DataReceived回调上的数据丢失



我在发布之前一直在寻找解决方案,但我放弃了!我只想使用标准输入进行交互式发送DOS命令。它运行良好,但我总是在输出dataReceived回调上获得最后一行(提示线)。

有什么想法?

Process p = null;
    private void Start_Click(object sender, EventArgs e)
    {
        p = new Process();
        p.StartInfo = new ProcessStartInfo();
        p.EnableRaisingEvents = true;
        p.StartInfo.CreateNoWindow = true;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.RedirectStandardError = true;
        p.StartInfo.RedirectStandardInput = true;
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.FileName = "cmd.exe";
        p.ErrorDataReceived += ErrorDataReceived;
        p.OutputDataReceived += OutputDataReceived;
        p.Start();
        p.BeginErrorReadLine();
        p.BeginOutputReadLine();
        p.StandardInput.WriteLine("dir");
    }
    private void OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        Console.WriteLine(e.Data + "n");
    }
    private void WriteToStandardInput_Click(object sender, EventArgs e)
    {
        p.StandardInput.WriteLine(txt_command.Text); //can be "dir" or "cd temp"
    }

添加p.standardinput.close()解决问题,原因是当您关闭输入流时,它实际上终止了该过程(您开始使用'p.start')。因此,正如我所说,您需要为每个命令启动单独的过程。

〜Nilesh

好吧,我找到了一个解决方案...我创建了2个任务,如下所示,这些任务正在从输出和错误流中不断读取并将其打印到富文本框中。诀窍不是使用BeginRorreadline和beginOutputReadline。我希望我能够帮助别人...

public partial class Form1 : Form
{
    private Process p = new Process();
    private SynchronizationContext context;
    public Form1()
    {
        InitializeComponent();
        context = SynchronizationContext.Current;
    }
    private void Start_Click (object sender, EventArgs e)
    {
        p.StartInfo = new ProcessStartInfo();
        p.EnableRaisingEvents = true;
        p.StartInfo.CreateNoWindow = true;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.RedirectStandardError = true;
        p.StartInfo.RedirectStandardInput = true;
        p.StartInfo.FileName = "cmd.exe";
        p.StartInfo.UseShellExecute = false;
        p.Start();
        Task.Run(() => ReadFromStreamLoop(p.StandardOutput));
        Task.Run(() => ReadFromStreamLoop(p.StandardError));
    }
    private void ReadFromStreamLoop (StreamReader s)
    {
        int count = 0;
        char[] buffer = new char[1024];
        do
        {
            StringBuilder builder = new StringBuilder();
            count = s.Read(buffer, 0, 1024);
            builder.Append(buffer, 0, count);
            context.Post(new SendOrPostCallback(delegate (object state)
            {
                richTextBox1.AppendText(builder.ToString());
            }), null);
        } while (count > 0);
    }
    private void WriteToStandardInput_Click (object sender, EventArgs e)
    {
        p.StandardInput.WriteLine(txt_command.Text); //can be "dir" or "cd temp"
    }
}

如果您正在寻找命令执行的事件结束,则每次产生新的过程。在处理结束时,您可以在主过程中显示提示。通过调用(主要)过程来管理您的环境变量。

请参阅-https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.outputdataareceivedtatareceived?view=netframework-4.7.7.2

最新更新