我打算做的是建立,除其他事项外,将嵌在它就像有些IDE做(事我觉得非常有用的)命令行应用程序。嵌入在C#WinForms应用程序一个CMD终端
这是我到目前为止,千万注意,这是一个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中为标准输出
- textbox3为标准错误
在我的问题:
我只能输入一个命令因为执行它后,我的CMD窗口消失。我知道它会因为我设置了info.CreateNoWindow = false;
而消失,它确实消失了,如果我尝试输入另一个命令,我会得到一个异常。
我该如何继续关于保持我的CMD窗口'活着',以便我可以尽可能多地使用它?总之我想真正模仿CMD行为。
如果有不清楚的地方,请随时索取更多信息。
额外的信息/我试了一下:
我试着加入info.Attributes = "/K";
,因为我知道,/K
应保持CMD活着。我也读过p.WaitForExit();
应该保持CMD活着,但从我认为这只是为了读取输出的目的。不用说,我不需要,因为我已经重定向了它的输出。这两种解决方案都不起作用,但我完全有可能以错误的方式使用它们。
我需要该进程以便我可以使用cd
轻松导航,并在需要时执行一系列命令,例如访问ftp
或mysql
时。我知道我可以通过参数解决这两个示例,但不适用于每个应用程序。总之,每次产生一个新进程都不是我想要的。我希望CMD接口始终处于运行状态。后
using(StreamWriter sw = p.StandardInput) {
if(sw.BaseStream.CanWrite) {
sw.WriteLine(textBox1.Text);
}
}
的CMD进程死掉了,但我不能查明原因。
'using'语句导致'p.StandardInput'被丢弃('sw'只是对它的引用)。不要那样做 - 代之以“p”(当你不再需要它时)。 –
@PieterWitvoet谢谢你的回答。所以,当我离开'使用'范围时,基本上p会被处置掉吗?如何在不使用'using'语句的情况下使用StreamWriter?我曾尝试在'Form1_Load'方法中声明StreamWriter,然后访问输出'p.StandardOutput',但是我的应用程序没有任何异常而挂起。你能否详细说明一下? – xIcarus
无论你使用什么,都会被放置在''using'块的末尾 - 所以每次你输入一个命令时,你的代码都会处理你的进程的标准输入。你基本上是在部署一个对象,并期望它继续像以前一样工作。只要删除'使用'语句。 'sw'不是您负责的新流编写器 - 它是对'p.StandardInput'的引用。处理'p'将为您处理这些流写入器。 –