【问题标题】:Adding scripting functionality to existing C# project向现有 C# 项目添加脚本功能
【发布时间】:2017-03-25 23:07:29
【问题描述】:

我在一个研究小组工作,我的任务是为数据采集程序添加脚本功能。理想情况下,我希望能够在数据采集软件运行时编写脚本(并将这些脚本保存为文件)。命令行也可能很好。

我对 C# 没有太多经验,但我确实有相当多的其他语言(Objective-C、Python)的编码经验。我看到这个链接https://blogs.msdn.microsoft.com/cdndevs/2015/12/01/adding-c-scripting-to-your-development-arsenal-part-1/ 详细介绍了“Roselyn 脚本包”,但我不确定这是否是我的最佳选择。

谁能建议获得完整脚本功能的最简单方法? (我试图避免在这里失去几个月的生命=p)。非常感谢您开始/建议的链接。

谢谢!

【问题讨论】:

    标签: c# scripting


    【解决方案1】:

    如果你愿意使用 IronPython,你可以直接在 C# 中执行脚本:

    using IronPython.Hosting;
    using Microsoft.Scripting.Hosting;
    
    private static void doPython()
    {
        ScriptEngine engine = Python.CreateEngine();
        engine.ExecuteFile(@"test.py");
    }
    

    Get IronPython here.

    【讨论】:

      【解决方案2】:

      您为我发布了一个有趣的链接,因为几周前我刚刚制作了类似的原型,但尚未实现。我的目标是在网页上创建一个 C#“即时”控制台。

      在以编程方式加载某些程序集方面存在一些小问题,并且必须明确引用它们。

      这是后面的代码,请稍后发布您的解决方案,我有兴趣知道。

      这允许在运行时编写 c# 代码并获得字符串返回。

      protected void getImmediateResult_Click(object sender, EventArgs e)
          {
      
              //building the code
              string source = @"using System; 
              class MyType{
              public static String Evaluate(){
              <!expression!>
              }}";
      
              string expression = this.txtimmediate.Text;
              string finalSource = source.Replace("<!expression!>", expression);
              textcodeCheck.Text = finalSource;
              var compileUnit = new CodeSnippetCompileUnit(finalSource);
      
              //preparing compilation
              CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
      
              // Create the optional compiler parameters
      
              //this correctly references the application but no System.Web etc
              string[] refArray = new string[2];
      
              UriBuilder uri = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase);
              refArray[0] = uri.Path;
      
              //this works
              refArray[1] = "System.Web" + ".dll";
      
              ////NOT WORKING for non microsoft assemblies
              //var allRefs = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
              //string[] refArray = new string[allRefs.Length + 1];
              //int i = 1;
              //foreach (AssemblyName refer in allRefs)
              //{
              //    refArray[i] = refer.Name + ".dll";
              //    i++;
              //}
      
              var compilerParameters = new CompilerParameters(refArray);
      
              CompilerResults compilerResults = provider.CompileAssemblyFromDom(compilerParameters, compileUnit);
              if (compilerResults.Errors.Count > 0)
              {
                  //1st error
                  this.txtResult.Text = compilerResults.Errors[0].ErrorText;
                  return;
              }
      
              //running it
              Type type = compilerResults.CompiledAssembly.GetType("MyType");
              MethodInfo method = type.GetMethod("Evaluate");
              String result = (String)method.Invoke(null, null);
      
      
              this.txtResult.Text = result;
          }
      

      【讨论】:

      • 如果您使用的是CodeDomCodeSnippetCompileUnitCSharpCodeProvider 等),则不需要那个 hackish 字符串源,您可以通过代码构建样板。
      • @Kroltan 你确定吗?我只是不想每次都输入类语法。
      • 我的意思是,样板可以在代码中构建,而不是从字符串中解析并替换。这样,您可以在 sn-p 而不是周围的样板中更可靠地报告错误。示例(使用 C#6,但可以轻松转换为其他版本):pastebin.com/5w86FrVb
      • 良好的链接,这样的方法将是干净的。对于任何开发人员来说,这种骇人听闻的方法乍看起来都更容易理解......
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-26
      • 2015-04-26
      • 1970-01-01
      • 2010-09-05
      相关资源
      最近更新 更多