C#通过调用系统命令执行R脚本

C#中调用命令执行R脚本,要实现这个功能我们得知道:(1)如何用c#调用系统命令;(2)如何用系统命令执行R脚本;(3)如何写R脚本

一、C#调用系统命令

    这里的“startInfo.FileName = "cmd.exe";”是通过C#调用的系统命令,当然你也可以执行cmd.exe,也可以执行其他的应用和程序,比如计算器“calc”,R程序“R.exe”等。这里的“string[] command”参数是要执行的命令语句,我这里是针对的是控制台,因为其他的应用程序我不知道怎么将参数传入程序中。

 1 /// <summary>  
 2         /// 执行DOS命令,返回DOS命令的输出  
 3         /// </summary>  
 4         /// <param name="dosCommand">dos命令</param>  
 5         /// <param name="milliseconds">等待命令执行的时间(单位:毫秒),  
 6         /// 如果设定为0,则无限等待</param>  
 7         /// <returns>返回DOS命令的输出</returns>  
 8         public string Execute(string[] command, int seconds = 10)
 9         {
10             string output = ""; //输出字符串  
11             if (command[0] != null && !command[0].Equals(""))
12             {
13                 Process process = new Process();//创建进程对象  
14                 ProcessStartInfo startInfo = new ProcessStartInfo();
15                 startInfo.FileName = "cmd.exe";//设定需要执行的命令  
16                 //startInfo.Arguments = "/C " + command;//“/C”表示执行完命令后马上退出 
17                 //startInfo.Arguments = command;//“/C”表示执行完命令后马上退出 
18                 startInfo.UseShellExecute = false;//不使用系统外壳程序启动  
19                 startInfo.RedirectStandardInput = true;  //重定向输入  
20                 startInfo.RedirectStandardOutput = true; //重定向输出  
21                 startInfo.CreateNoWindow = true;//不创建窗口  
22                 process.StartInfo = startInfo;
23                 try
24                 {
25                     if (process.Start())//开始进程  
26                     {
27                         if (seconds == 0)
28                         {
29                             process.WaitForExit();//这里无限等待进程结束  
30                         }
31                         else
32                         {
33                             process.WaitForExit(seconds); //等待进程结束,等待时间为指定的毫秒  
34                         }
35                         StreamWriter sw = process.StandardInput;
36                         sw.WriteLine(command[0]);
37                         sw.WriteLine(command[1]);
38                         sw.Close();
39                         //process.StandardInput.Close();
40                         output = process.StandardOutput.ReadToEnd();//读取进程的输出  
41                     }
42                 }
43                 catch
44                 {
45                 }
46                 finally
47                 {
48                     if (process != null)
49                         process.Close();
50                 }
51             }
52             return output;
53         }
c#调用系统命令

二、 用系统命令执行R脚本

    先说明一下用控制台执行R脚本,而之后的用C#调用系统命令执行R脚本就是将这些控制台的语句当作参数传入上面的string[] command数组中

1、将R.exe所在路径加到环境变量path下,路径一般为C:\Program Files\R\R-3.0.1\bin或者在控制台中敲入要转入的目录。

2、在windows 命令行中敲入 调用命令:r CMD BATCH D:\RWORKSPACE\CMD_TEST.R  (注意 CMD BATCH 都要大写)

命令的普遍形式为R CMD command file,command是别的工具。比如前面用到的批处理工具BATCH

这样它就在执行R脚本了。我的测试脚本很简单,当然你可以写的很复杂,执行你要完成的任务。

        

结果它会生成一个rasterName.csv的结果文件和执行状态的文件Test.r.Rout文件

三、 写R脚本

     当然你可以很简单的在记事本中写R脚本,但是为了应用程序的可交互性,你可以用代码在记事本中写脚本,但是要注意的是文件路径的问题。因为在R程序中的路径是“\\”或者“/”的,你的代码中可以将获取的路径的符号其替换为“\\\\”或者“/”。不然无法读取文件。

 1 /// <summary>
 2         /// 创建随机森林影像分类R脚本
 3         /// </summary>
 4         /// <param name="rowCount"></param>
 5         /// <param name="columnCount"></param>
 6         /// <param name="bandCount"></param>
 7         /// <param name="workPath"></param>
 8         /// <param name="roiPath"></param>
 9         /// <param name="rasterPath"></param>
10         public void CreateRandomForestScript(int rowCount=2850, int columnCount=2850, int bandCount=4, string workPath = @"D:", string roiPath = "", string rasterPath = "")
11         {
12             string scriptPath = System.IO.Path.GetFullPath(workPath) + @"\randomForest.r";
13             workPath = workPath.Replace("\\", "\\\\"); //workPath = workPath.Replace('\\', '/');
14             roiPath = roiPath.Replace("\\", "\\\\");
15             rasterPath = rasterPath.Replace("\\", "\\\\");
16             string resultName = "rasterResult.txt";
17             string str = "";
18             string funStr = "";
19             using (StreamWriter sr = new StreamWriter(scriptPath,false,Encoding.GetEncoding("GB2312")))
20             {
21                 str = "setwd('"+workPath+"')\n";
22                 str += "library(randomForest)\n";
23                 str += "roi<-read.table('" + roiPath + "')\n";
24                 //str += "roi<-read.table(file.choose())\n";
25                 str += "raster<-read.table('" + rasterPath + "')\n";
26                 //str += "raster<-read.table(file.choose())\n";
27                 funStr = "V" + (bandCount + 1) + "~";
28                 for (int i = 0; i < bandCount;i++)
29                 {
30                     funStr += "V" + (i + 1)+"+";
31                 }
32                 funStr = funStr.Remove(funStr.Length-1);
33                 str += "spam<-randomForest("+funStr+",data=roi)\n";
34                 //str += "spam<-randomForest(V5~V1+V2+V3+V4,data=roi)\n";
35                 str += "rm(roi)\n";
36                 str += "gc()\n";
37                 str += "c<-predict(spam,raster,type='response')\n";
38                 str += "rm(spam)\n";
39                 str += "rm(raster)\n";
40                 str += "gc()\n";
41                 str += "e<-unlist(c)\n";
42                 str += "result<-matrix(e,nrow="+rowCount+",ncol="+columnCount+")\n";
43                 str += "rm(c)\n";
44                 str += "rm(e)\n";
45                 str += "gc()\n";
46                 str += "write.table(result, '" + resultName + "')\n";
47                 str += "rm(result)\n";
48                 str += "gc()\n";
49                 sr.WriteLine(str);
50                 sr.Close();
51             }
52         }
代码创建脚本

这是写的创建随机森林影像分类的脚本的函数,产生的脚本文件如下:

四、 调用系统命令执行R脚本

主要的是command 参数那两行代码

 1  private void buttonOK_Click(object sender, EventArgs e)
 2         {
 3             try
 4             {
 5                 if (workPath == "" || roiPath == "" || rasterPath == "" || textBoxX1.Text == "" || textBoxX2.Text == "")
 6                     return;
 7                 rowCount = Convert.ToInt32(textBoxX1.Text);
 8                 columnCount = Convert.ToInt32(textBoxX2.Text);
 9                 bandCount = Convert.ToInt32(integerInput1.Value);
10                 RandomForestClassfier randomForest = new RandomForestClassfier();
11                 randomForest.CreateRandomForestScript(rowCount, columnCount, bandCount, workPath, roiPath, rasterPath);
12                 string[] command = new string[2];
13                 command[0] = "cd /d C:\\Program Files\\R\\R-3.2.1\\bin\\x64";
14                 command[1] = "r CMD BATCH "+workPath+@"\randomForest.r";
15                 randomForest.RunRandomForestScript(command);
16                 MessageBox.Show("影像分类完成", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
17             }
18             catch (Exception ex)
19             {
20                 MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
21             }
22         }
调用系统命令执行脚本

五、 参考资料

1.http://www.jb51.net/article/57477.htm

2.http://www.jb51.net/article/26993.htm

3.http://q.cnblogs.com/q/44086/

4.http://blog.csdn.net/diyiziran/article/details/21379181

5.http://book.2cto.com/201305/21969.html

 

 

 

 

posted @ 2015-08-22 16:42  羽过天晴  阅读(3227)  评论(0编辑  收藏  举报