【问题标题】:Creating a Command Prompt创建命令提示符
【发布时间】:2015-06-11 16:42:01
【问题描述】:

我想在 WPF 中创建一个命令提示符,用户可以在其中键入命令并在同一窗口中获取输出,这与原始命令提示符的工作原理完全相同。

最初我使用Process.Start() 并将其放入另一个线程以不阻塞主线程。我使用 StreamReader 和 StreamWriter 来编写和捕获输出。但是我无法连续监听输出或编写命令。

这是我到目前为止的代码 -

public class TerminalController
{
    public Process CmdProcess { get; set; }
    public StreamReader Reader { get; set; }
    public StreamWriter Writer { get; set; }
    public void Init()
    {
        if (CmdProcess != null)
        {
            try
            {
                Close();
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
            }
        }
        CmdProcess = new Process();
        System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
        startInfo.FileName = "cmd";
        startInfo.WindowStyle = ProcessWindowStyle.Normal;
        startInfo.CreateNoWindow = true;
        startInfo.RedirectStandardInput = true;
        startInfo.RedirectStandardOutput = true;
        startInfo.UseShellExecute = false;
        CmdProcess.StartInfo = startInfo;
        CmdProcess.Start();
        Writer = CmdProcess.StandardInput;

        StartReading();
    }
    public void Init(string command)
    {
        if (CmdProcess != null)
        {
            try
            {
                Close();
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
            }
        }
        CmdProcess = new Process();
        System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
        startInfo.FileName = "cmd";
        startInfo.WindowStyle = ProcessWindowStyle.Normal;
        startInfo.CreateNoWindow = true;
        startInfo.RedirectStandardInput = true;
        startInfo.RedirectStandardOutput = true;
        startInfo.UseShellExecute = false;
        CmdProcess.StartInfo = startInfo;
        CmdProcess.Start();

    }

    private void Write(String command)
    {
        using (Writer = CmdProcess.StandardInput)
        {
            Writer.Write(command);
        }
    }

    private void StartReading()
    {
        using (Reader = CmdProcess.StandardOutput)
        {
            RaiseTerminalReadEvent(null, Reader.ReadToEnd());
        }
    }
    public async void RunCommand(String command)
    {
        RaiseTerminalWriteEvent(command);
        await Task.Run(() => Write(command));
        await Task.Run(() => StartReading());
        //Close();
    }

    public Task InitAsync()
    {
        return Task.Run(() => Init());
    }

    public void Close()
    {
        try
        {
            CmdProcess.Close();
            Reader.Close();
            Writer.Close();
            CmdProcess = null;
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
        }
    }

    internal Task RunCommandAsync(string command)
    {
        return Task.Run(() => RunCommand(command));
    }
}

我只能运行一次命令,这是我发送 dir 命令时的输出 -

dir
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

E:\Microsoft\WPF\Example\Example\bin\Debug>More? 

如果我再次发送命令,它会给出以下异常 -

Cannot write to a closed TextWriter.
at System.IO.__Error.WriterClosed()
   at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
   at System.IO.StreamWriter.Write(String value)
   at Example.Controllers.TerminalController.Write(String command) in e:\Microsoft\WPF\Example\Example\Controllers\TerminalController.cs:line 91

那么我怎样才能连续运行命令并监听输出。我需要每次都创建一个新流程吗?还有其他选择吗?

【问题讨论】:

    标签: c# wpf process stream


    【解决方案1】:

    您的 using 块会在您第一次使用流时立即处理它们。

    因此,您不能再次使用它们。

    不要那样做。

    【讨论】:

    • 啊,是的,这是主要问题。我通过收听读取事件解决了其余代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-13
    • 2014-07-25
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 2011-04-02
    相关资源
    最近更新 更多