从 c# 应用程序执行 ScriptCS
本文关键字:ScriptCS 执行 应用程序 | 更新日期: 2023-09-27 18:33:20
Background
我正在创建一个运行一些状态检查的 c# 应用程序(想想 nagios 样式检查(。
理想情况下,我想要的是这个 c# 应用程序查看特定目录,只需编译/执行其中的任何 scriptcs 脚本,并根据结果采取行动(例如,针对失败的状态检查发送电子邮件警报(。
我希望脚本返回一个整数或其他东西(例如(,并且该整数将指示状态检查成功或失败。
值返回到 C# 应用程序。
0 - Success
1 - Warning
2 - Error
当第一次执行此任务时,我认为这是 MEF 的工作,但创建这些"状态检查"而无需创建项目或编译任何内容会方便得多,只需在文件夹中放置一个 scriptcs 脚本似乎更有吸引力。
所以我的问题是
是否有任何关于同时使用 c# 应用程序和脚本的文档/示例(谷歌没有给我带来太多(?
这是脚本的用例,还是从未真正打算像这样使用?
使用 roslyn 或一些动态编译/执行创建自定义解决方案会更容易吗?(我对脚本的经验很少(
我找到了一些关于如何做到这一点的简单例子:
从磁盘上的文件加载脚本并运行它:https://github.com/glennblock/scriptcs-hosting-example
一个网站,您可以在其中提交代码,它将返回结果:https://github.com/filipw/sample-scriptcs-webhost
下面是如何加载脚本文件、运行它并返回结果的示例:
public dynamic RunScript()
{
var logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
var scriptServicesBuilder = new ScriptServicesBuilder(new ScriptConsole(), logger).
LogLevel(LogLevel.Info).Cache(false).Repl(false).ScriptEngine<RoslynScriptEngine>();
var scriptcs = scriptServicesBuilder.Build();
scriptcs.Executor.Initialize(new[] { "System.Web" }, Enumerable.Empty<IScriptPack>());
scriptcs.Executor.AddReferences(Assembly.GetExecutingAssembly());
var result = scriptcs.Executor.Execute("HelloWorld.csx");
scriptcs.Executor.Terminate();
if (result.CompileExceptionInfo != null)
return new { error = result.CompileExceptionInfo.SourceException.Message };
if (result.ExecuteExceptionInfo != null)
return new { error = result.ExecuteExceptionInfo.SourceException.Message };
return result.ReturnValue;
}
问题 2:脚本语言在这种情况下可以很好地工作,只要你对它们有所了解。
问题3:就个人而言,我会使用 CS-Script - 它维护得很好,并且有很多文档。
对不起,如果我有点跑题了,但这个问题点燃了我的想象力,我想...
IMMO 脚本更多的是它自己的脚本环境,有点像 NodeC 之类的东西......它不需要任何东西来提供开箱即用的脚本环境。但据我所知.不向 .NET 应用程序提供托管 API。当然,我可能是错的,这将是查看来源的问题,因为从文档中我也找不到参考;
在我看来,你会更好地整合罗斯林 api你自己。
编辑:我错了,ScriptCs scriptcs.hosting Nuget 包是入口点,我可以在这里看到 Glimpse 和 MakeSharp 是如何做到的;
但是有 EdgeJs,开箱即用几乎可以为您提供您想要的东西,但脚本将是 NodeJs 上的 Javascript,但它似乎不是您想要的。
如果您尝试加载怎么办c#脚本直接从Edge,它可以编译python,F#,c#,csx的...但它也是从 Node env 而不是 .net 完成的(或者我错过了什么?
无论如何。。。我突然想到你可以从.Net加载Edge,再次从Node加载Edge并调用.Net脚本,该脚本又会再次向.Net返回一些内容。
这感觉有点矫枉过正,但隔离得非常好,可能值得一试。 除了一些设置之外,没有太多代码可以编写。
我在GitHub上加载了实验。
问题 1。我做了一个(丑陋的(示例集成测试,使用 System.Diagnostics.Process.Start(( 从 C# 执行 ScriptCS(在这种情况下涉及 Powershell(我希望我不应该回答你的第一个问题。
[Test, Explicit]
public void RunScriptCsFile_FilePrintsTheValue2_StreamIsParsedCorrectly() {
var scriptFile = @"C:'Projects'test-project'test-project.Tests'test-file.csx";
var param = string.Format("scriptcs {0}", scriptFile);
Process executeScript = new Process {
StartInfo = new ProcessStartInfo {
FileName = "powershell.exe",
Arguments = param,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
executeScript.Start();
var value = -1;
while (!executeScript.StandardOutput.EndOfStream) {
string line = executeScript.StandardOutput.ReadLine();
if (int.TryParse(line, out value)) {
Assert.AreEqual(2, value);
}
}
}
test-file.csx 仅包含Console.WriteLine("2");
作为案例的"错误"示例。
问题3.我已经用Shovel ScriptPack for ScriptCS做了类似的事情,可能值得一试。