从C#编程使用cmd.exe

时间:2013-04-11 08:55:10

标签: c# command-line process

  1. 我想从C#在cmd.exe上运行一系列命令。
  2. 我只需要打开一个cmd窗口
  3. 我需要在执行完成后和完成后保持cmd窗口打开。
  4. 我需要在已打开的cmd窗口[/ edit] 中显示 [edit]命令以及命令的输出。
  5. 所以基本上我想打开并使用cmd.exe,就像手动用户一样。 我尝试了一些方法,但没有人可以完成以上所有4项。

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

    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");
        }
    }
    

2 个答案:

答案 0 :(得分: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继续运行。

答案 1 :(得分: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();
            }