在CMA终端中嵌入CMD终端

时间:2015-10-12 10:37:48

标签: c# process createprocess

我打算做的是构建一个应用程序,除其他外,它将嵌入一个命令行,就像某些IDE一样(我发现它非常有用)。

这是我到目前为止的代码,注意它是一个Winforms项目:

public partial class Form1 : Form
    {
        Process p = new Process();
        ProcessStartInfo info = new ProcessStartInfo();

        public Form1() {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e) {
            info.FileName = "cmd.exe";
            info.RedirectStandardInput = true;
            info.RedirectStandardOutput = true;
            info.RedirectStandardError = true;
            info.UseShellExecute = false;
            info.CreateNoWindow = true;

            p.StartInfo = info;
            p.Start();
        }

        private void button1_Click(object sender, EventArgs e) {
            using(StreamWriter sw = p.StandardInput) {
                if(sw.BaseStream.CanWrite) {
                    sw.WriteLine(textBox1.Text);
                }
            }
            textBox2.Text = p.StandardOutput.ReadToEnd();
            textBox3.Text = p.StandardError.ReadToEnd();
            p.WaitForExit();
        }
    }
}

正如您所看到的,有3个文本框和一个按钮:

  • textbox1用于输入命令
  • textbox2适用于stdout
  • textbox3适用于stderr

关于我的问题:

我只能输入一个命令,因为在执行它之后,我的CMD窗口就会消失。我知道它已经消失了,因为我设置了info.CreateNoWindow = false;它确实消失了,如果我尝试输入另一个命令,我会得到一个例外。

我将如何继续保持我的CMD窗口“活着”?所以我可以尽可能多地使用它?总之,我想真正模仿CMD行为。

如果不清楚,请随时询问更多信息。

额外信息/我尝试了什么:

我尝试添加info.Attributes = "/K";因为我知道/K应该让CMD保持活力。我还读到p.WaitForExit();应该让CMD保持活着,但从我的想法来看,这只是为了读取输出。不用说,我不需要那个,因为我已经重定向了它的输出。这些解决方案都不起作用,但我完全有可能以错误的方式使用它们。

我需要该进程处于活动状态,因此我可以使用cd轻松导航并在需要时执行一系列命令,例如访问ftpmysql时。我知道我可以使用参数解决这两个示例,但不适用于每个应用程序。简而言之,每次产生一个新的过程都不是我想要的。我希望CMD接口始终处于运行状态。

cmd进程在

之后死亡
using(StreamWriter sw = p.StandardInput) {
    if(sw.BaseStream.CanWrite) {
        sw.WriteLine(textBox1.Text);
    }
}

但我无法确定原因。

1 个答案:

答案 0 :(得分:0)

CMD控制台提供的是执行预定义功能的接口(在System32或%PATH%中)。 进程类也具有相同的功能,您可以做的是当用户输入命令文本并按下textbox2中的返回键(可以是多行,黑色背景,白色文本),您可以通过命令文本到Process p = new Process();并附加结果,使其看起来像单个cmd会话。在传递整个命令文本之前,我们需要分隔在第一个空格之后出现的文本(如果有的话)。例如:

SHUTDOWN /S /T 10

其中Shutdown为filename,/ S / T 10为参数。

在执行ProcessStartInfo的set default目录之前: -

_processStartInfo.WorkingDirectory = @"%Path%";

否则默认为System32文件夹。