【问题标题】:Execute ScriptCS from c# application从 c# 应用程序执行 ScriptCS
【发布时间】:2016-02-01 05:40:06
【问题描述】:

背景

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

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

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

返回给 C# 应用程序的值。

0 - Success
1 - Warning
2 - Error

当我第一次接受这个任务时,我认为这是 MEF 的工作,但是创建这些“状态检查”会更加方便,而无需创建项目或编译任何东西,只需在文件夹中放置一个 scriptcs 脚本似乎更有吸引力。

所以我的问题是

  1. 是否有任何关于同时使用 c# 应用程序和脚本的文档/示例(谷歌并没有让我了解多少)?

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

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

【问题讨论】:

    标签: c# scriptcs


    【解决方案1】:

    我找到了一些很好的简单示例来说明如何做到这一点:

    从磁盘上的文件加载脚本并运行它: 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】:

      问题 2: 只要您对脚本语言有所了解,脚本语言就可以在这种情况下很好地工作

      问题 3: 我个人使用CS-Script 维护良好,并且有很多相关文档

      【讨论】:

        【解决方案3】:

        对不起,如果我跑题了,但这个问题激发了我的想象力, 我想...

        IMMO scriptcs 更像是它自己的脚本环境,有点像 NodeCs 之类的东西...... 它不需要任何东西来提供开箱即用的脚本环境。 但据我所见。不向 .net 应用程序提供托管 API。 当然我可能是错的,这将是查看源代码的问题,因为从文档中我也找不到参考;

        在我看来,你自己集成 Roslyn api 会更好。

        编辑:我错了,ScriptCs scriptcs.hosting Nuget packages 是入口点,我可以看到here是如何Glimpse的,MakeSharp是如何做到的;

        但是有EdgeJs,开箱即用,几乎可以满足您的需求,但脚本将是 NodeJs 上的 Javascript,但这似乎不是您想要的。

        如果您尝试加载怎么办 直接来自 Edge 的 c# 脚本,它可以编译 python、F#、c#、csx 的 ... 但它也是从 Node env 做的,而不是 .net(或者我错过了什么?)

        无论如何...在我看来,您可以从 .Net 加载 Edge 再次从 Node 加载 Edge 并调用 .Net 脚本,该脚本将反过来再次将某些内容返回给 .Net。

        这感觉有点矫枉过正,但又如此孤立,值得一试。除了一些设置之外,没有太多需要编写的代码。

        我在GitHub上加载了实验。

        【讨论】:

          【解决方案4】:

          问题 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。我为 ScriptCS 使用 Shovel ScriptPack 做了类似的事情,可能值得一试。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-01
            • 2010-09-09
            • 1970-01-01
            • 1970-01-01
            • 2016-03-22
            • 1970-01-01
            相关资源
            最近更新 更多