从 c# 应用程序执行 ScriptCS

本文关键字:ScriptCS 执行 应用程序 | 更新日期: 2023-09-27 18:33:20

Background

我正在创建一个运行一些状态检查的 c# 应用程序(想想 nagios 样式检查(。

理想情况下,我想要的是这个 c# 应用程序查看特定目录,只需编译/执行其中的任何 scriptcs 脚本,并根据结果采取行动(例如,针对失败的状态检查发送电子邮件警报(。

我希望脚本返回一个整数或其他东西(例如(,并且该整数将指示状态检查成功或失败。

值返回到 C# 应用程序。

0 - Success
1 - Warning
2 - Error

当第一次执行此任务时,我认为这是 MEF 的工作,但创建这些"状态检查"而无需创建项目或编译任何内容会方便得多,只需在文件夹中放置一个 scriptcs 脚本似乎更有吸引力。

所以我的问题是

  1. 是否有任何关于同时使用 c# 应用程序和脚本的文档/示例(谷歌没有给我带来太多(?

  2. 这是脚本的用例,还是从未真正打算像这样使用?

  3. 使用 roslyn 或一些动态编译/执行创建自定义解决方案会更容易吗?(我对脚本的经验很少(

从 c# 应用程序执行 ScriptCS

我找到了一些关于如何做到这一点的简单例子:

从磁盘上的文件加载脚本并运行它: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做了类似的事情,可能值得一试。