2015-10-12 26 views
1

我打算做的是建立,除其他事项外,将嵌在它就像有些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轻松导航,并在需要时执行一系列命令,例如访问ftpmysql时。我知道我可以通过参数解决这两个示例,但不适用于每个应用程序。总之,每次产生一个新进程都不是我想要的。我希望CMD接口始终处于运行状态。后

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

的CMD进程死掉了,但我不能查明原因。

+0

'using'语句导致'p.StandardInput'被丢弃('sw'只是对它的引用)。不要那样做 - 代之以“p”(当你不再需要它时)。 –

+0

@PieterWitvoet谢谢你的回答。所以,当我离开'使用'范围时,基本上p会被处置掉吗?如何在不使用'using'语句的情况下使用StreamWriter?我曾尝试在'Form1_Load'方法中声明StreamWriter,然后访问输出'p.StandardOutput',但是我的应用程序没有任何异常而挂起。你能否详细说明一下? – xIcarus

+0

无论你使用什么,都会被放置在''using'块的末尾 - 所以每次你输入一个命令时,你的代码都会处理你的进程的标准输入。你基本上是在部署一个对象,并期望它继续像以前一样工作。只要删除'使用'语句。 'sw'不是您负责的新流编写器 - 它是对'p.StandardInput'的引用。处理'p'将为您处理这些流写入器。 –

回答

0

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

SHUTDOWN /S /T 10 

其中关机将文件名和/ S/T 10将参数。

执行的ProcessStartInfo设置默认目录之前: -

_processStartInfo.WorkingDirectory = @"%Path%"; 

否则默认将System32文件夹中。

+0

这实际上是一个想法,我也考虑过并在C++应用程序中实现它。不幸的是,这只是真实情况的一个阴影,一个模拟,一个解决方法。不是实际的解决方案。这正是我在C#中重写类似应用程序的原因。但是,感谢您的意见,我会保留这作为最后的手段。 – xIcarus

相关问题