通过 C# 从 RScript 捕获标准输出
capturing stdout from RScript via C#
我正在尝试 运行 使用位于 R 安装的 \bin\ 目录中的 RScript.exe 的 R 脚本。 运行 windows 命令行中的 RScript 将结果写入屏幕。当我尝试使用 System.Diagnostics.Process() 在 C# 中进行复制时,输出似乎丢失了。
举个简单的例子,我将忽略我的实际 r 代码,只尝试从 RScript.exe 读取版本信息。当 运行 来自 cmd 提示符时:
rscript --version
我在屏幕上看到了
R scripting front-end version 3.2.3 (2015-12-10)
当我在此 C# 代码中执行相同操作时,没有捕获任何内容。
StringBuilder outputBuilder = new StringBuilder();
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "rscript";
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.ErrorDialog = false;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Arguments = "--version";
proc.EnableRaisingEvents = true;
proc.OutputDataReceived += new DataReceivedEventHandler
(
delegate(object sender, DataReceivedEventArgs e)
{
outputBuilder.Append(e.Data);
}
);
proc.ErrorDataReceived += new DataReceivedEventHandler
(
delegate(object sender, DataReceivedEventArgs e)
{
outputBuilder.Append(e.Data);
}
);
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.WaitForExit();
string allOutput = outputBuilder.ToString();
看起来这应该很简单,但是尽管看了很多从 c# 捕获 stdout 的示例,但我仍然感到困惑。
按照下面的方法尝试。
使用Process.StandardOutput
属性。 (您已经将 RedirectStandardOutput
设置为 true)。
这个returns一个StreamReader
可以用来读取应用程序的标准输出流。
例如:
开始进程后..
string output = proc.StandardOutput.ReadToEnd();
查看下方 link 了解更多详情。
https://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput(v=vs.110).aspx
你必须在 WaitForExit()
之前打电话。以上link解释了大部分后果。
这最终对我有用,我不确定到底是什么问题,因为它看起来与原始版本几乎相同。
public void test()
string exe = @"C:\Program Files\R\R-3.5.2\bin\x64\Rscript.exe";
System.Diagnostics.Process proc = new System.Diagnostics.Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.WorkingDirectory = Path.GetDirectoryName(exe);
psi.Arguments = "--version";
psi.FileName = exe;
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.CreateNoWindow = true;
proc.StartInfo = psi;
proc.ErrorDataReceived += consoleDataReceived;
proc.OutputDataReceived += consoleDataReceived;
proc.EnableRaisingEvents = true;
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
while (!proc.HasExited)
{
Thread.Sleep(100);
}
//this flushes the rest of the messages out.
proc.WaitForExit();
}
public void consoleDataReceived(object sender, DataReceivedEventArgs e)
{
string strMessage = e.Data;
Console.WriteLine(e.Data);
}
我正在尝试 运行 使用位于 R 安装的 \bin\ 目录中的 RScript.exe 的 R 脚本。 运行 windows 命令行中的 RScript 将结果写入屏幕。当我尝试使用 System.Diagnostics.Process() 在 C# 中进行复制时,输出似乎丢失了。
举个简单的例子,我将忽略我的实际 r 代码,只尝试从 RScript.exe 读取版本信息。当 运行 来自 cmd 提示符时:
rscript --version
我在屏幕上看到了
R scripting front-end version 3.2.3 (2015-12-10)
当我在此 C# 代码中执行相同操作时,没有捕获任何内容。
StringBuilder outputBuilder = new StringBuilder();
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "rscript";
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.ErrorDialog = false;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Arguments = "--version";
proc.EnableRaisingEvents = true;
proc.OutputDataReceived += new DataReceivedEventHandler
(
delegate(object sender, DataReceivedEventArgs e)
{
outputBuilder.Append(e.Data);
}
);
proc.ErrorDataReceived += new DataReceivedEventHandler
(
delegate(object sender, DataReceivedEventArgs e)
{
outputBuilder.Append(e.Data);
}
);
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.WaitForExit();
string allOutput = outputBuilder.ToString();
看起来这应该很简单,但是尽管看了很多从 c# 捕获 stdout 的示例,但我仍然感到困惑。
按照下面的方法尝试。
使用Process.StandardOutput
属性。 (您已经将 RedirectStandardOutput
设置为 true)。
这个returns一个StreamReader
可以用来读取应用程序的标准输出流。
例如: 开始进程后..
string output = proc.StandardOutput.ReadToEnd();
查看下方 link 了解更多详情。
https://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput(v=vs.110).aspx
你必须在 WaitForExit()
之前打电话。以上link解释了大部分后果。
这最终对我有用,我不确定到底是什么问题,因为它看起来与原始版本几乎相同。
public void test()
string exe = @"C:\Program Files\R\R-3.5.2\bin\x64\Rscript.exe";
System.Diagnostics.Process proc = new System.Diagnostics.Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.WorkingDirectory = Path.GetDirectoryName(exe);
psi.Arguments = "--version";
psi.FileName = exe;
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.CreateNoWindow = true;
proc.StartInfo = psi;
proc.ErrorDataReceived += consoleDataReceived;
proc.OutputDataReceived += consoleDataReceived;
proc.EnableRaisingEvents = true;
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
while (!proc.HasExited)
{
Thread.Sleep(100);
}
//this flushes the rest of the messages out.
proc.WaitForExit();
}
public void consoleDataReceived(object sender, DataReceivedEventArgs e)
{
string strMessage = e.Data;
Console.WriteLine(e.Data);
}