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