通过C#从RScript捕获stdout

时间:2017-11-30 22:49:48

标签: c# r stdout rscript

我正在尝试使用位于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的例子,但我还是很难过。

2 个答案:

答案 0 :(得分:0)

尝试如下所述。

使用Process.StandardOutput属性。 (您已将RedirectStandardOutput设置为true)。

返回StreamReader,可用于读取应用程序的标准输出流。

例如: 在开始这个过程之后..

string output = proc.StandardOutput.ReadToEnd();

请查看以下链接了解更多详情。

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

您必须在WaitForExit()之前致电。以上链接解释了大部分后果。

答案 1 :(得分:0)

这最终对我有用,我不确定问题出在哪里,因为它看起来几乎与原始问题相同。

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);
}