我如何从c#执行命令行程序,并获得STD OUT结果?具体来说,我想对两个以编程方式选择的文件执行DIFF,并将结果写入一个文本框。
当前回答
朱利安的解决方案经过了一些小的修正。下面是一个同样使用https://sourceforge.net/projects/bat-to-exe/ GenericConsole.cs和https://www.codeproject.com/Articles/19225/Bat-file-compiler program.txt作为args部分的例子:
using System;
using System.Text; //StringBuilder
using System.Diagnostics;
using System.IO;
class Program
{
private static bool redirectStandardOutput = true;
private static string buildargument(string[] args)
{
StringBuilder arg = new StringBuilder();
for (int i = 0; i < args.Length; i++)
{
arg.Append("\"" + args[i] + "\" ");
}
return arg.ToString();
}
static void Main(string[] args)
{
Process prc = new Process();
prc.StartInfo = //new ProcessStartInfo("cmd.exe", String.Format("/c \"\"{0}\" {1}", Path.Combine(Environment.CurrentDirectory, "mapTargetIDToTargetNameA3.bat"), buildargument(args)));
//new ProcessStartInfo(Path.Combine(Environment.CurrentDirectory, "mapTargetIDToTargetNameA3.bat"), buildargument(args));
new ProcessStartInfo("mapTargetIDToTargetNameA3.bat");
prc.StartInfo.Arguments = buildargument(args);
prc.EnableRaisingEvents = true;
if (redirectStandardOutput == true)
{
prc.StartInfo.UseShellExecute = false;
}
else
{
prc.StartInfo.UseShellExecute = true;
}
prc.StartInfo.CreateNoWindow = true;
prc.OutputDataReceived += OnOutputDataRecived;
prc.ErrorDataReceived += OnErrorDataReceived;
//prc.Exited += OnExited;
prc.StartInfo.RedirectStandardOutput = redirectStandardOutput;
prc.StartInfo.RedirectStandardError = redirectStandardOutput;
try
{
prc.Start();
prc.BeginOutputReadLine();
prc.BeginErrorReadLine();
prc.WaitForExit();
}
catch (Exception e)
{
Console.WriteLine("OS error: " + e.Message);
}
prc.Close();
}
// Handle the dataevent
private static void OnOutputDataRecived(object sender, DataReceivedEventArgs e)
{
//do something with your data
Console.WriteLine(e.Data);
}
//Handle the error
private static void OnErrorDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(e.Data);
}
// Handle Exited event and display process information.
//private static void OnExited(object sender, System.EventArgs e)
//{
// var process = sender as Process;
// if (process != null)
// {
// Console.WriteLine("ExitCode: " + process.ExitCode);
// }
// else
// {
// Console.WriteLine("Process exited");
// }
//}
}
代码需要在VS2007内部编译,使用命令行csc.exe生成的可执行文件将不能正确显示控制台输出,甚至崩溃与CLR20r3错误。注释掉OnExited事件过程,蝙蝠到exe的控制台输出将更像原来的蝙蝠控制台输出。
其他回答
一行运行命令:
new Process() { StartInfo = new ProcessStartInfo("echo", "Hello, World") }.Start();
以最短的可读代码量读取命令输出:
var cliProcess = new Process() {
StartInfo = new ProcessStartInfo("echo", "Hello, World") {
UseShellExecute = false,
RedirectStandardOutput = true
}
};
cliProcess.Start();
string cliOut = cliProcess.StandardOutput.ReadToEnd();
cliProcess.WaitForExit();
cliProcess.Close();
这里有一个小例子:
using System;
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
var p = Process.Start(
new ProcessStartInfo("git", "branch --show-current")
{
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
WorkingDirectory = Environment.CurrentDirectory
}
);
p.WaitForExit();
string branchName =p.StandardOutput.ReadToEnd().TrimEnd();
string errorInfoIfAny =p.StandardError.ReadToEnd().TrimEnd();
if (errorInfoIfAny.Length != 0)
{
Console.WriteLine($"error: {errorInfoIfAny}");
}
else {
Console.WriteLine($"branch: {branchName}");
}
}
}
我相信这是最短的形式。
请注意,大多数命令行工具很容易混淆标准输出和标准错误,有时将它们组合成一个字符串是有意义的。
p.e exitcode有时也很有用。
上面的例子用于编写命令行工具,如果你想自己做的话。请注意,对于cli自动化,也可以使用Cake Frosten和Cake Git扩展。
如果你不介意引入依赖,CliWrap可以为你简化:
using CliWrap;
using CliWrap.Buffered;
var result = await Cli.Wrap("target.exe")
.WithArguments("arguments")
.ExecuteBufferedAsync();
var stdout = result.StandardOutput;
这可能不是最好/最简单的方法,但可能是一种选择:
当从代码执行时,添加“> output.txt”,然后读入output.txt文件。
我发现还有一个有用的参数,我用它来消除流程窗口
pProcess.StartInfo.CreateNoWindow = true;
这有助于从用户完全隐藏黑色控制台窗口,如果这是你想要的。
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 如何从终端/命令行调用VS代码编辑器
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 在Jar文件中运行类
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 如何在Windows命令提示符下运行.sh ?
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?