C〓〓シナリオエンジンCS-Scriptの使用


最近はプログラムにCシリーズのスクリプトエンジンを組み込みたいですが、NET Fraamewark時代にはCS-Scriptというものを使っていました。いい感じです。今もサポートしています。NET Coreを見つけました。埋め込みしてみます。
比較
C((zhi)シナリオを実行できるソリューションといえば、RosynとMonoがあります。彼らよりCS-Scriptが提供できるパッケージの方がもっと高級です。その下の階にはRosynなどのエンジンで動作しています。その上、いくつかの追加機能を提供しています。
  • 完全なC〓ファイルを実行します。
  • 外部プロセスによってC〓ファイル
  • を実行する。
  • 実行中に、複数のcxiファイルをリンクし、実行
  • を統合する。
  • 簡単な方法でリンクする
  • を提供します。
  • スクリプトデバッグ機能
  • 注:技術の発展によって、多くの機能がRosynに支持されたかもしれません。同時にwebに基づいてTry.NETやSharpLabなどの優れたプランがあります。
    もちろん自分でRosynに基づいてこれらの機能を実現することもできますが、CS-Scriptはもっと簡単なパッケージを提供して、怠け者に適用します。
    使用
    プログラムは.NET 5の開発に基づいて、CS-Scriptパッケージを引用してみて、あまり使いにくいことを発見しました。System.Reflection.Target Invocation Exception:「Exception has been thrown by the target of an invocation.」サポート.NET Coreは、実際にはCS-cript.oreというパッケージで、インストールすればいいです。
    
    Install-Package CS-Script.Core
    CS-Scriptは、実際の下層はMono/Rosyn/CodeDomの3つのシナリオエンジンをサポートしています。NET COREの特殊性のため、CS-Script.oreは削除しました。Rosynのエンジンにしか対応できません。サポートされているC言語バージョンはRosynのバージョンによって決定されます。
    他のものは言わないで、直接コードを入れます。
    
    using CSScriptLib;
    using System;
    using System.Reflection;
    
    namespace ConsoleApp3
    {
      public class Program
      {
        static void Main(string[] args)
        {
          //var eval = CSScript.Evaluator.ReferenceAssemblyByNamespace("System.Text");
          //var p = eval.ReferenceAssemblyByNamespace("ConsoleApp3");
          Assembly compilemethod = CSScript.RoslynEvaluator.CompileMethod(
                @"using System;
                 public static void CompileMethod(string greeting)
                 {
                   Console.WriteLine(""CompileMethod:"" + greeting);
                 }");
          var p = compilemethod.GetType("css_root+DynamicClass");
          var me = p.GetMethod("CompileMethod");
          me.Invoke(null, new object[] { "1" });
    
    
          //eval = CSScript.Evaluator.ReferenceAssembly(sqr);
          dynamic loadmethod = CSScript.Evaluator.LoadMethod(@"using System;
                 public void LoadMethod(string greeting)
                 {
                   Console.WriteLine(""LoadMethod:"" +greeting);
                 }");
          loadmethod.LoadMethod("Hello World!");
    
    
          dynamic loadcode = CSScript.Evaluator
           .LoadCode(@"using System;
    using ConsoleApp31;
    using System.Text;
    public class ScriptCC
    {
      public void LoadCode(string greeting)
      {
        Console.WriteLine(""LoadCode:"" + greeting);
      }
    }");
          loadcode.LoadCode("111");
    
          var eval = CSScript.Evaluator.ReferenceDomainAssemblies(DomainAssemblies.AllStaticNonGAC);
    
          var ass = eval
     .CompileCode(@"using System;
    public static class ScriptCCStatic
    {
      public static void LoadCodeStatic(string greeting)
      {
        Console.WriteLine(""LoadCodeStatic:"" + greeting);
      }
    }");
          var tp = eval.CreateDelegate(@"int Sqr(int a)
                            {
                              return a * a;
                            }");
          Console.WriteLine(tp(3));
    
          eval = eval.ReferenceDomainAssemblies(DomainAssemblies.AllStaticNonGAC);
          Assembly compilecode = eval
          .CompileCode(@"using System;
    using ConsoleApp31;//    namespace          。
    using System.Text;
    using ConsoleApp3;
    public class ScriptLC
    {
      public void CompileCode(string greeting)
      {
        Console.WriteLine(""CompileCode:"" + greeting + Encoding.ASCII.IsBrowserDisplay);
        Program.Write();
        Test.Send();
      }
    }");
          var ps = compilecode.GetType("css_root+ScriptLC");
          var obj = compilecode.CreateInstance("css_root+ScriptLC");
          var mes = ps.GetMethod("CompileCode");
          mes.Invoke(obj, new object[] { "1" });
          Console.WriteLine();
    
          //  evaluator      
          var ww = eval.GetReferencedAssemblies();
          foreach (var n in ww)
          {
            if (n.GetName().Name.Contains("System")) continue;
            if (n.GetName().Name.Contains("Microsoft")) continue;
            if (n.GetName().Name.Contains("CS")) continue;
            Console.WriteLine("AseemblyName: " + n.GetName());
            foreach (var wn in n.GetTypes())
            {
              Console.WriteLine("Types: " + wn.Name);
            }
          }
          Console.WriteLine();
    
          //    AppDomain      
          foreach (var n in AppDomain.CurrentDomain.GetAssemblies())
          {
            if (n.GetName().Name.Contains("System")) continue;
            if (n.GetName().Name.Contains("Microsoft")) continue;
            if (n.GetName().Name.Contains("CS")) continue;
            Console.WriteLine("AseemblyName: " + n.GetName());
            foreach (var wn in n.GetTypes())
            {
              Console.WriteLine("Types: " + wn.Name);
            }
          }
          Console.ReadKey();
        }
    
        public static void Write()
        {
          Console.WriteLine("REFERENCE OK");
        }
      }
    }
    
    締め括りをつける
    CS-Script.oreを使用する場合は、すべてのロード/コンパイルの方法とタイプがCurrenntApDomainに動的に加わり、メインプログラムで呼び出すことができます。Evaaluator.ReferenceAsmblyなどの関数で引用を追加します。他の動的コンパイルのコードセグメントを引用することはサポートされていません。
    現在のApp DomainのプログラムセットをEvaalatorに一括で参照することができますが、同じようにファイルに定義されているプログラムセットのみを呼び出して、他のダイナミックプログラムセットをロードできません。Evaalutor.Referencedomann Asssembilies(Domain Asmbilies.All)を起動するとエラーが表示されます。
    この制限はRosynによるもので、しばらくは解決できません。複数のコードセグメントの相互呼び出しが必要な場合は、直接コードセグメントをつなぎ合わせたり、共通のコードセグメントをファイルに保存したりして、ファイルから呼び出します。
    CompleMethod
    コンパイル方法は、ダイナミックに生成されたプログラムセットに戻ります。メソッドはデフォルトでDynamicClassクラスにロードされます。このTypeは完全に名称をcss_と定義しています。root+DynamicClassで定義された静的方法は、以下のように呼び出される必要があります。
    
    var p = compilemethod.GetType("css_root+DynamicClass");
    var me = p.GetMethod("CompileMethod");
    me.Invoke(null, new object[] { "1" });
    LoadMethod
    ローディング方法は、デフォルトクラスのオブジェクトに戻り、リターンオブジェクトをdynamicタイプと定義することにより、インスタンスメソッドを直接呼び出すことができます。
    
    loadmethod.LoadMethod("Hello World!");
    LoadCode
    クラスをロードして、コードセグメントの最初のクラスの例を返します。リターンオブジェクトがdynamicタイプであると定義することによって、インスタンスメソッドを直接呼び出すことができます。
    
    loadcode.LoadCode("111");
    CopileCode
    クラスをコンパイルし、動的に生成されたプログラムセットを返します。定義された例示的な方法は、以下のように呼び出されます。
    
    var ps = compilecode.GetType("css_root+ScriptLC");
    var obj = compilecode.CreateInstance("css_root+ScriptLC");
    var mes = ps.GetMethod("CompileCode");
    mes.Invoke(obj, new object[] { "1" });
    Console.WriteLine();
    CreateDelegate
    一つの依頼を生成して、DynamicClassと同じ定義で直接呼び出すことができます。
    
    var tp = eval.CreateDelegate(@"int Sqr(int a)
                      {
                        return a * a;
                      }");
    Console.WriteLine(tp(3));
    参考資料
    Rosynを通して直接台本を使う方法を添付します。Rosyn Scripptings-PI-Sempples.md
    以上はC((zhi)脚本エンジンCS-Scriptの使用の詳細です。C(zhi)脚本エンジンCS-Scriptに関する資料は他の関連記事に注目してください。