请教C#高手,关于如何用代码调用命令行(cmd),得到其输出?

比如,手动在装了java的Win7命令行输入java -version,会得到如下输出

我写的代码如下,但却要不就报错要不就什么也不输出。

请问哪里错了?

其实可以直接用java.exe 命令,不用cmd.exe ,如下代码:

using System;
using System.ComponentModel;
using System.Diagnostics;

namespace ProcessDemo
{
class Program
{
static void Main(string[] args)
{
try {
Process p = new Process();

p.StartInfo.FileName = "java.exe";
p.StartInfo.Arguments = "-version";
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;

p.Start();
p.WaitForExit();

String result = p.StandardOutput.ReadToEnd();
if (String.IsNullOrEmpty(result)) {
Console.WriteLine("StandardOutput是空的。");
}

result = p.StandardError.ReadToEnd();

Console.WriteLine(result);

} catch(Win32Exception e){
Console.WriteLine(e.Message);
}

Console.WriteLine("Program end");
Console.ReadKey();
}
}
}

 运行结果:

温馨提示:答案为网友推荐,仅供参考
第1个回答  2015-02-09
 // 用 cmd.exe 需要重定向输入,下面使用了两种不种的方法获取 java 版本信息 
 [STAThread]
   public static void Main(string[] args)
   {
       var version1 = GetJavaVersion1();
       Console.WriteLine(version1);
 
       Console.WriteLine();
 
       var version2 = GetJavaVersion12();
       Console.WriteLine(version2);
 
       Console.WriteLine();
       Console.ReadKey();
   }
 
   private static string GetJavaVersion1()
   {
       var process = new Process();
       process.StartInfo.FileName = @"C:\Program Files\Java\jre7\bin\java.exe";
       process.StartInfo.Arguments = "-version";
       process.StartInfo.RedirectStandardError = true;
       process.StartInfo.RedirectStandardOutput = true;
       process.StartInfo.UseShellExecute = false;
 
       process.Start();
 
       process.WaitForExit();
 
       var output = process.StandardOutput.ReadToEnd(); // 这里输出是 ""
       output = process.StandardError.ReadToEnd(); // 我测试是输出到 Error 中的, 不知道是为什么*/
 
       return output;
   }
 
   private static string GetJavaVersion12()
   {
       var process = new Process();
       process.StartInfo.FileName = "cmd.exe";
       process.StartInfo.RedirectStandardInput = true;
       process.StartInfo.RedirectStandardError = true;
       process.StartInfo.RedirectStandardOutput = true;
       process.StartInfo.UseShellExecute = false;
 
       process.Start();
 
       var standardInput = process.StandardInput;
 
       standardInput.WriteLine(@"""C:\Program Files\Java\jre7\bin\java.exe"" -version");
 
       standardInput.Close();
 
       var output = process.StandardOutput.ReadToEnd(); // 这里是输出 cmd 说明
       output = process.StandardError.ReadToEnd(); // 我测试是输出到 Error 中的, 不知道是为什么*/
 
       return output;
   }

追问

谢了,你的两个函数只是为了说明你的思考调试过程吧,第二个与采纳的答案类似。不过还有高手告诉我可以用 cmd /c java -version这样的命令。

追答

 /c 表示命令执行完成后结束 cmd 进度。你可以在控制台中使用 cmd /? 查看说明。可以使用如下方式调用

[STAThread]
    public static void Main(string[] args)
    {
        var process = new Process();
        process.StartInfo.FileName = "cmd.exe";
        process.StartInfo.Arguments = @"/c ""C:\Program Files\Java\jre7\bin\java.exe"" -version";
        process.StartInfo.RedirectStandardInput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.UseShellExecute = false;
 
        process.Start();
        process.WaitForExit();
 
        var output = process.StandardError.ReadToEnd();
 
        Console.WriteLine(output);
        Console.ReadKey();
 
    }

追问

代码我早就有了,不过我搜过/c也没看到什么详细的解释。你能不能解释清楚为什么不用/c就得不到输出?

追答

因为 process start 了 cmd.exe 后,进程并没有结束。就好象手工打开命令行,但是不输出 exit ,命令行窗口会就一直存在。这样调用 Standard***.ReadToEnd 就会一直等待。而使用 /c 参数后,命令执行完成 cmd.exe 就退出了,这样就能使用 readtoend 函数读取程序执行结果了。

还有命令行帮助可以在控制台下使用 cmd /? 查看,我这里第二行就是 /c 的说明。

追问

你的意思是说进程退出了才能ReadToEnd()成功?

追答

手册上说只有 process 写入数据到流中或是关闭流, ReadToEnd 才能完成

https://msdn.microsoft.com/zh-cn/library/system.diagnostics.process.standardoutput(v=vs.110).aspx

我这里测试使用 cmd.exe 而不加 /c 参数的话 ReadToEnd 函数会一直阻塞无法返回。你可以试试看。
你可以在调用 ReadToEnd 前调用 process.HasExited 看看进程是不是已经退出了。

追问

谢谢了,你写得很耐心,不过已经采纳了别人了。研究到此为止吧。

第2个回答  2015-02-09
static void Main(string[] args)
        {
            Process p = new Process(); 
            p.StartInfo.FileName = "cmd.exe"; 
            p.StartInfo.UseShellExecute = false; 
            p.StartInfo.RedirectStandardInput = true; 
            p.StartInfo.RedirectStandardOutput = true; 
            p.StartInfo.CreateNoWindow = true; 
            p.Start(); 
            p.StandardInput.WriteLine("ipconfig"); 
            p.StandardInput.WriteLine("exit"); 
            p.WaitForExit();
            Console.WriteLine(p.StandardOutput.ReadToEnd()); 
            p.Close();
            Console.ReadKey();
        }

 不知道是不是你要的!

追问

你这个我运行倒是出来了,但我测试了java -version这个命令,还是什么都没输出。你试试看?

追答

那你把

p.StandardInput.WriteLine("ipconfig");

 改成

p.StandardInput.WriteLine("C:\\Users\\xfh378\\java -version");

 试试!

追问

试过了,不行的。

相似回答