1
  1. 我想从 C# 在 cmd.exe 上运行一系列命令。
  2. 我只需要打开一个cmd窗口
  3. 我需要在执行过程中和完成后保持 cmd 窗口打开。
  4. 我需要在打开的 cmd 窗口 [/edit] 中显示命令 [edit]以及命令的输出。

所以基本上我想像手动用户一样打开和使用 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");
    }
}
4

2 回答 2

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 继续运行。

于 2013-04-11T09:36:02.890 回答
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();
            }
于 2013-04-11T09:23:51.017 回答