2013-04-11 34 views
1
  1. 我想运行在C#在cmd.exe的一系列命令。
  2. 我只需要打开一个cmd窗口
  3. 我需要保持cmd窗口在执行过程中以及完成之后保持打开状态。
  4. 我需要显示在打开cmd窗口[/编辑]的命令[编辑]执行以及命令的输出。

所以基本上我想打开并使用cmd.exe就像手动用户一样。 我尝试了一些方法,但没有人能做到以上所有4项。编程使用的cmd.exe从C#

下面的代码工作,但不显示命令/输出,并在完成后终止。 有什么帮助吗?

Process p = new Process(); 
ProcessStartInfo info = new ProcessStartInfo("cmd.exe"); 
info.RedirectStandardInput = true; 
info.UseShellExecute = false; 
info.CreateNoWindow = false; 
info.Arguments = "/k"; 

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

using (StreamWriter sw = p.StandardInput) 
{ 
    if (sw.BaseStream.CanWrite) 
    { 
     sw.WriteLine("dir"); 
     sw.WriteLine("ipconfig"); 
    } 
} 
+0

您的代码工作并显示命令/输出:) – I4V 2013-04-11 09:22:44

回答

4

RedirectStandard...-属性具有误导性。只要您设置其中一个,所有三个流都将被重定向。这是因为底层Windows API只有一个标志来控制重定向 - STARTF_USESTDHANDLES

因为您没有将RedirectStandardOutput属性设置为true,所以stdout流不会提供给您的代码,而是会被重定向到您自己的进程的Console.Out流。 因此,只要父进程是控制台应用程序,您的代码就可以正常工作;但在Windows应用程序中,输出会被重定向到虚无。

一个简单的解决办法是暂时把你的父进程到一个控制台应用程序:

[DllImport("kernel32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool AllocConsole(); 

[DllImport("kernel32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool FreeConsole(); 

static void Main(string[] args) 
{ 
    Process p = new Process(); 
    ProcessStartInfo info = new ProcessStartInfo("cmd.exe"); 
    info.RedirectStandardInput = true; 
    info.UseShellExecute = false; 
    info.CreateNoWindow = false; 

    p.StartInfo = info; 
    AllocConsole(); 
    p.Start(); 
    FreeConsole(); 


    using (StreamWriter sw = p.StandardInput) 
    { 
     if (sw.BaseStream.CanWrite) 
     { 
      sw.WriteLine("dir"); 
      sw.WriteLine("ipconfig"); 
     } 
    } 
} 

至于保持控制台打开:你可以只取出FreeConsole()调用,这样父进程保持周围甚至控制台在cmd.exe退出后。但是,如果您需要多个控制台,则这可能会成为问题,因为您的父级进程一次无法与多个控制台关联。

或者,不要关闭输入流,以便cmd.exe保持运行。

+0

谢谢丹尼尔,我想知道为什么输出被重定向甚至当我没有将RedirectStandardOutput设置为true时,在调试时进行调试。你的代码几乎可以做到我需要的东西。但是有2个限制。 1-我只能打开一个你指出的控制台。 2 - 如果我关闭控制台,应用程序终止,我不想要。是否有可能创建一个子进程并从该运行该控制台,以便它将成为一个独立的控制台或子进程共享控制台? – hkn 2013-04-11 10:29:14

+0

如果您调用'FreeConsole()',则不会发生这两个问题。在这种情况下,你必须保持输入流打开(不要使用''block),这样cmd.exe才能继续运行。 – Daniel 2013-04-11 10:37:49

+0

我确实尝试过,但它只是导致控制台挂起而没有做任何事情。当我尝试它释放构建它虽然工作像一个魅力虽然:)仍然它的作品,所以谢谢 – hkn 2013-04-11 12:22:45

0

对于看到了把插入Console.ReadLine();(应用程序停止,直到你发送一个键,就可以看到结果)执行命令后。

static void Main(string[] args) 
      { 
       Process p = new Process(); 
       ProcessStartInfo info = new ProcessStartInfo("cmd.exe"); 
       info.RedirectStandardInput = true; 
       info.UseShellExecute = false; 
       info.CreateNoWindow = false; 

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

       using (StreamWriter sw = p.StandardInput) 
       { 
        if (sw.BaseStream.CanWrite) 
        { 
         sw.WriteLine("dir"); 

         sw.WriteLine("ipconfig"); 
        } 
       } 
       Console.ReadLine(); 
      } 
+0

感谢IRSOG,但我需要打开的cmd窗口上显示的命令和输出不只是读取到内存 – hkn 2013-04-11 10:40:18