Created
May 3, 2014 12:10
-
-
Save odugen/e1bce24416d0f5848f37 to your computer and use it in GitHub Desktop.
C# runs R code from CMD using string.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.IO; | |
| using System; | |
| class Program | |
| { | |
| static void Main() | |
| { | |
| var batch = @" | |
| print(""start""); | |
| args <- commandArgs(trailingOnly = TRUE) | |
| print(args[1]); | |
| print(""hello world""); | |
| "; | |
| REngineRunner.RunFromCmd(batch, "a"); | |
| } | |
| public static class REngineRunner | |
| { | |
| public static void RunFromCmd(string batch, params string[] args) | |
| { | |
| // Not required. But our R scripts use allmost all CPU resources if run multiple instances | |
| lock (typeof(REngineRunner)) | |
| { | |
| string file = string.Empty; | |
| string result = string.Empty; | |
| try | |
| { | |
| // Save R code to temp file | |
| file = TempFileHelper.CreateTmpFile(); | |
| using (var streamWriter = new StreamWriter(new FileStream(file, FileMode.Open, FileAccess.Write))) | |
| { | |
| streamWriter.Write(batch); | |
| } | |
| // Get path to R | |
| var rCore = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\R-core") ?? | |
| Registry.CurrentUser.OpenSubKey(@"SOFTWARE\R-core"); | |
| var is64Bit = Environment.Is64BitProcess; | |
| if (rCore != null) | |
| { | |
| var r = rCore.OpenSubKey(is64Bit ? "R64" : "R"); | |
| var installPath = (string)r.GetValue("InstallPath"); | |
| var binPath = Path.Combine(installPath, "bin"); | |
| binPath = Path.Combine(binPath, is64Bit ? "x64" : "i386"); | |
| binPath = Path.Combine(binPath, "Rscript"); | |
| string strCmdLine = @"/c """ + binPath + @""" " + file; | |
| if (args.Any()) | |
| { | |
| strCmdLine += " " + string.Join(" ", args); | |
| } | |
| var info = new ProcessStartInfo("cmd", strCmdLine); | |
| info.RedirectStandardInput = false; | |
| info.RedirectStandardOutput = true; | |
| info.UseShellExecute = false; | |
| info.CreateNoWindow = true; | |
| using (var proc = new Process()) | |
| { | |
| proc.StartInfo = info; | |
| proc.Start(); | |
| result = proc.StandardOutput.ReadToEnd(); | |
| } | |
| } | |
| else | |
| { | |
| result += "R-Core not found in registry"; | |
| } | |
| Console.WriteLine(result); | |
| } | |
| catch (Exception ex) | |
| { | |
| throw new Exception("R failed to compute. Output: " + result, ex); | |
| } | |
| finally | |
| { | |
| if (!string.IsNullOrWhiteSpace(file)) | |
| { | |
| TempFileHelper.DeleteTmpFile(file, false); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| /// <summary> | |
| /// | |
| /// </summary> | |
| /// <see cref="http://www.daveoncsharp.com/2009/09/how-to-use-temporary-files-in-csharp/"/> | |
| public class TempFileHelper | |
| { | |
| public static string CreateTmpFile(bool throwException = true) | |
| { | |
| string fileName = string.Empty; | |
| try | |
| { | |
| // Get the full name of the newly created Temporary file. | |
| // Note that the GetTempFileName() method actually creates | |
| // a 0-byte file and returns the name of the created file. | |
| fileName = Path.GetTempFileName(); | |
| // Craete a FileInfo object to set the file's attributes | |
| var fileInfo = new FileInfo(fileName); | |
| // Set the Attribute property of this file to Temporary. | |
| // Although this is not completely necessary, the .NET Framework is able | |
| // to optimize the use of Temporary files by keeping them cached in memory. | |
| fileInfo.Attributes = FileAttributes.Temporary; | |
| } | |
| catch (Exception ex) | |
| { | |
| if(throwException) | |
| { | |
| throw new Exception("Unable to create TEMP file or set its attributes: " + ex.Message, ex); | |
| } | |
| } | |
| return fileName; | |
| } | |
| public static void DeleteTmpFile(string tmpFile, bool throwException = true) | |
| { | |
| try | |
| { | |
| // Delete the temp file (if it exists) | |
| if (File.Exists(tmpFile)) | |
| { | |
| File.Delete(tmpFile); | |
| } | |
| } | |
| catch (Exception ex) | |
| { | |
| if (throwException) | |
| { | |
| throw new Exception("Error deleteing TEMP file: " + ex.Message, ex); | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment