从 .NET 应用程序 (C#) 捕获控制台输出
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/186822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Capturing console output from a .NET application (C#)
提问by Gripsoft
How do I invoke a console application from my .NET application and capture all the output generated in the console?
如何从我的 .NET 应用程序调用控制台应用程序并捕获控制台中生成的所有输出?
(Remember, I don't want to save the information first in a file and then relist as I would love to receive it as live.)
(请记住,我不想先将信息保存在文件中,然后再重新发布,因为我希望以实时方式接收它。)
采纳答案by mdb
This can be quite easily achieved using the ProcessStartInfo.RedirectStandardOutputproperty. A full sample is contained in the linked MSDN documentation; the only caveat is that you may have to redirect the standard error stream as well to see all output of your application.
使用ProcessStartInfo.RedirectStandardOutput属性可以很容易地实现这一点。完整示例包含在链接的 MSDN 文档中;唯一需要注意的是,您可能还必须重定向标准错误流才能查看应用程序的所有输出。
Process compiler = new Process();
compiler.StartInfo.FileName = "csc.exe";
compiler.StartInfo.Arguments = "/r:System.dll /out:sample.exe stdstr.cs";
compiler.StartInfo.UseShellExecute = false;
compiler.StartInfo.RedirectStandardOutput = true;
compiler.Start();
Console.WriteLine(compiler.StandardOutput.ReadToEnd());
compiler.WaitForExit();
回答by Franci Penov
Use ProcessInfo.RedirectStandardOutputto redirect the output when creating your console process.
在创建控制台进程时使用ProcessInfo.RedirectStandardOutput重定向输出。
Then you can use Process.StandardOutputto read the program output.
然后您可以使用Process.StandardOutput读取程序输出。
The second link has a sample code how to do it.
第二个链接有一个示例代码如何做到这一点。
回答by livetogogo
From PythonTR - Python Programc?lar? Derne?i, e-kitap, ?rnek:
来自PythonTR - Python Programc?lar?Derne?i、e-kitap、?rnek:
Process p = new Process(); // Create new object
p.StartInfo.UseShellExecute = false; // Do not use shell
p.StartInfo.RedirectStandardOutput = true; // Redirect output
p.StartInfo.FileName = "c:\python26\python.exe"; // Path of our Python compiler
p.StartInfo.Arguments = "c:\python26\Hello_C_Python.py"; // Path of the .py to be executed
回答by Dinis Cruz
I've added a number of helper methods to the O2 Platform(Open Source project) which allow you easily script an interaction with another process via the console output and input (see http://code.google.com/p/o2platform/source/browse/trunk/O2_Scripts/APIs/Windows/CmdExe/CmdExeAPI.cs)
我在O2 平台(开源项目)中添加了许多辅助方法,允许您通过控制台输出和输入轻松编写与另一个进程的交互脚本(请参阅http://code.google.com/p/o2platform/源/浏览/主干/O2_Scripts/APIs/Windows/CmdExe/CmdExeAPI.cs)
Also useful for you might be the API that allows the viewing of the console output of the current process (in an existing control or popup window). See this blog post for more details: http://o2platform.wordpress.com/2011/11/26/api_consoleout-cs-inprocess-capture-of-the-console-output/(this blog also contains details of how to consume the console output of new processes)
同样对您有用的可能是允许查看当前进程的控制台输出(在现有控件或弹出窗口中)的 API。有关更多详细信息,请参阅此博客文章:http: //o2platform.wordpress.com/2011/11/26/api_consoleout-cs-inprocess-capture-of-the-console-output/(此博客还包含有关如何使用的详细信息新进程的控制台输出)
回答by SlavaGu
ConsoleAppLauncheris an open source library made specifically to answer that question. It captures all the output generated in the console and provides simple interface to start and close console application.
ConsoleAppLauncher是一个专门用来回答这个问题的开源库。它捕获控制台中生成的所有输出,并提供简单的界面来启动和关闭控制台应用程序。
The ConsoleOutput event is fired every time when a new line is written by the console to standard/error output. The lines are queued and guaranteed to follow the output order.
每当控制台将新行写入标准/错误输出时,都会触发 ConsoleOutput 事件。行排队并保证遵循输出顺序。
Also available as NuGet package.
也可用作NuGet 包。
Sample call to get full console output:
获取完整控制台输出的示例调用:
// Run simplest shell command and return its output.
public static string GetWindowsVersion()
{
return ConsoleApp.Run("cmd", "/c ver").Output.Trim();
}
Sample with live feedback:
带有实时反馈的示例:
// Run ping.exe asynchronously and return roundtrip times back to the caller in a callback
public static void PingUrl(string url, Action<string> replyHandler)
{
var regex = new Regex("(time=|Average = )(?<time>.*?ms)", RegexOptions.Compiled);
var app = new ConsoleApp("ping", url);
app.ConsoleOutput += (o, args) =>
{
var match = regex.Match(args.Line);
if (match.Success)
{
var roundtripTime = match.Groups["time"].Value;
replyHandler(roundtripTime);
}
};
app.Run();
}
回答by Sergei Zinovyev
Added process.StartInfo.**CreateNoWindow** = true;
and timeout
.
添加process.StartInfo.**CreateNoWindow** = true;
和timeout
。
private static void CaptureConsoleAppOutput(string exeName, string arguments, int timeoutMilliseconds, out int exitCode, out string output)
{
using (Process process = new Process())
{
process.StartInfo.FileName = exeName;
process.StartInfo.Arguments = arguments;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
output = process.StandardOutput.ReadToEnd();
bool exited = process.WaitForExit(timeoutMilliseconds);
if (exited)
{
exitCode = process.ExitCode;
}
else
{
exitCode = -1;
}
}
}
回答by Shital Shah
This is bit improvement over accepted answer from @mdb. Specifically, we also capture error output of the process. Additionally, we capture these outputs through events because ReadToEnd()
doesn't work if you want to capture botherror and regular output. It took me while to make this work because it actually also requires BeginxxxReadLine()
calls after Start()
.
这是对@mdb接受的答案的一点改进。具体来说,我们还捕获流程的错误输出。此外,我们通过捕捉这些事件的输出,因为ReadToEnd()
如果你想捕捉不起作用两个错误和常规输出。我花了一段时间才完成这项工作,因为它实际上还需要BeginxxxReadLine()
在Start()
.
Asynchronous way:
异步方式:
using System.Diagnostics;
Process process = new Process();
void LaunchProcess()
{
process.EnableRaisingEvents = true;
process.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_OutputDataReceived);
process.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_ErrorDataReceived);
process.Exited += new System.EventHandler(process_Exited);
process.StartInfo.FileName = "some.exe";
process.StartInfo.Arguments = "param1 param2";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
//below line is optional if we want a blocking call
//process.WaitForExit();
}
void process_Exited(object sender, EventArgs e)
{
Console.WriteLine(string.Format("process exited with code {0}\n", process.ExitCode.ToString()));
}
void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(e.Data + "\n");
}
void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(e.Data + "\n");
}
回答by 3dGrabber
I made a reactive version that accepts callbacks for stdOut and StdErr.onStdOut
and onStdErr
are called asynchronously,
as soon as data arrives (before the process exits).
我制作了一个响应式版本,它接受 stdOut 和 StdErr 的回调。onStdOut
并且onStdErr
在
数据到达时(在进程退出之前)被异步调用。
public static Int32 RunProcess(String path,
String args,
Action<String> onStdOut = null,
Action<String> onStdErr = null)
{
var readStdOut = onStdOut != null;
var readStdErr = onStdErr != null;
var process = new Process
{
StartInfo =
{
FileName = path,
Arguments = args,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = readStdOut,
RedirectStandardError = readStdErr,
}
};
process.Start();
if (readStdOut) Task.Run(() => ReadStream(process.StandardOutput, onStdOut));
if (readStdErr) Task.Run(() => ReadStream(process.StandardError, onStdErr));
process.WaitForExit();
return process.ExitCode;
}
private static void ReadStream(TextReader textReader, Action<String> callback)
{
while (true)
{
var line = textReader.ReadLine();
if (line == null)
break;
callback(line);
}
}
Example usage
示例用法
The following will run executable
with args
and print
下面将运行executable
与args
和打印
- stdOut in white
- stdErr in red
- 白色的标准输出
- 红色的 stdErr
to the console.
到控制台。
RunProcess(
executable,
args,
s => { Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(s); },
s => { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(s); }
);