使用 .R 文件作为资源并直接在 C# 中创建批处理
Posted
技术标签:
【中文标题】使用 .R 文件作为资源并直接在 C# 中创建批处理【英文标题】:Using a .R file as a resource and create a batch directly in C# 【发布时间】:2020-05-30 10:12:42 【问题描述】:我有许多闪亮的应用程序,文件结构为 global.R、ui.R、server.R 和我称之为 batchTrigger.R 的东西。后者的内容简直就是以下——
.libPath(*Path to my R Package Repository*)
require('shiny')
runApp(*Path to the folder with the aforementioned files*)
我使用以下代码创建了一个名为 application.cmd 的批处理文件-
cls
@pushd ""
:::::::::::::::::::
@echo off
ECHO Loading...Please, wait. The Application will open automatically.
ECHO ---
ECHO Do not close this console window for the whole duration of your session
ECHO in the application.
ECHO ---
@echo off
"C:\Program Files\R\bin\Rscript.exe" ".../**batchTrigger.R**"
:::::::::::::::::::
@popd
cmd /k
这个批处理文件运行良好。然后我更进一步,决定创建一个包含多个 R 应用程序的 windows 窗体。我在表单中有两个按钮,每个按钮都像这样-
private void application1_click(object sender, EventArgs e)
System.Diagnostics.Process cmd = new Process();
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.FileName = "...\\**application1.cmd**";
cmd.StartInfo.Arguments = "/K";
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.RedirectStandardInput = true;
cmd.Start();
到目前为止,一切都很好。两个按钮都按预期工作。我想更进一步,但由于我是 C# 的新手,我需要帮助。我希望得到的是解决方案中如此部署的应用程序中 R 文件和 cmd 文件的动态位置。换句话说,我应该能够在 C# 代码in 中编写批处理文件的内容,并且 batchTrigger.R 的路径应该随着 Windows 窗体应用程序的位置而变化(这将是一个自包含部署的可执行文件)。这个想法是 R 包存储库和 R 安装可能保持静态,并且可以分别由 batchTrigger.R 和 application.cmd 指向,但是 batchTrigger.R 本身的位置以及其他 R 文件随应用程序移动。我认为 resource.resx 可以对此做点什么,但我究竟该怎么做,我似乎不明白。任何建议将不胜感激。
【问题讨论】:
您是否考虑过将 bat 文件中您想要动态化的部分作为参数传递给 bat 脚本?这可能更简单。 我刚刚意识到我的想法中犯了一个错误。 global.R、ui.R 和 server.R 文件的位置由 batchTrigger.R 文件指向,它本身不是原生格式。话虽如此,@Dweeberly,我喜欢你的建议。我可以在 R 脚本中创建可以从外部获取的参数,如果 C# 可以以某种方式将应用程序的当前位置作为 csv 抛出我,我也许可以将其作为我的 R 脚本的主目录读入 batchTrigger .R 文件。你认为这是一个好方法吗? 我不能说有一条“正确”的路径,但是让你的 C# 调用带有参数的脚本会提供额外的灵活性,因为你可能会在未来找到更容易修改你的脚本文件,而不是重新编译你的 C#。 GetCurrentDirectory 应该会为您提供您正在工作的目录。 真的很好奇为什么不直接从 c# 启动 Rscript。编写启动rscript的批处理文件并从c#启动批处理文件是添加不必要的中间人 【参考方案1】:制作一个通用方法:
private void StartSilentR(string rScriptFilePath)
System.Diagnostics.Process cmd = new Process();
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.FileName = @"C:\Program Files\R\bin\Rscript.exe";
cmd.StartInfo.Arguments = rScriptFilePath;
cmd.StartInfo.CreateNoWindow = false;
//avoid this unless you must control the app via stdin
//cmd.StartInfo.RedirectStandardInput = true;
cmd.Start();
然后在确定脚本的位置后编写一些调用它的东西。例如,如果您的目录结构为:
RLauncherCSharpApp.exe
rscripts\ui.R
rscripts\global.R
rscripts\batchTrigger.R
然后在c#中你可以:
//take exe Path, remove exe name and add rscripts folder and batchtrigger.R file name
var rbt = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "rscripts", "batchTrigger.R");
StartSilentR(rbt);
或者,假设您要搜索应用文件夹的所有子文件夹,以查找所有名为 batchTrigger.R 的文件:
var exeFolder = Path.GetDirectoryName(Application.ExecutablePath);
string[] paths = Directory.GetFiles(exeFolder, "batchTrigger.R", SearchOption.AllDirectories);
//maybe add them to a list view and the user can click one to launch ..
【讨论】:
以上是关于使用 .R 文件作为资源并直接在 C# 中创建批处理的主要内容,如果未能解决你的问题,请参考以下文章