最近想要在程序中嵌入一个C#脚本引擎,在.NET Framework时代用过一个叫做CS-Script的东西,感觉还是不错,发现现在也支持.NET Core了,试着嵌入一下。 ## 比较 要说能够运行C#脚本的解决方案,有Roslyn和Mono,与他们相比,CS-Script能够提供的封装更为高级,它底层是通过Roslyn之类的引擎运行的,在此基础上,提供了一些额外功能: * 执行完整的C#文件 * 通过外部进程执行C#文件 * 在运行过程中链接多个c#文件,并集成运行 * 提供简便的方法进行链接 * 脚本调试功能 > 注:由于技术发展,很多功能可能已经被Roslyn支持了。同时基于web有[Try.NET](
)和[SharpLab](
)等优秀方案。 当然也可以自己基于Roslyn去实现这些功能,不过CS-Script提供了更加简单的封装,适用于懒人。 ## 使用 程序基于.NET 5的开发,尝试引用`CS-Script`包,发现不太好用,一直提示*System.Reflection.TargetInvocationException:“Exception has been thrown by the target of an invocation.”*。支持.NET Core的实际上是`CS-Script.Core`这个包,安装即可。 ```powershell Install-Package CS-Script.Core ``` `CS-Script`实际上底层支持Mono/Roslyn/CodeDom三种脚本引擎,由于.NET CORE的特殊性,CS-Script.Core做了删减,只能支持Roslyn一种引擎了,支持的C#语言版本由Roslyn版本决定。 旁的不说,直接上代码: ```c# using CSScriptLib; using System; using System.Reflection; namespace ConsoleApp3 { public class Program { static void Main(string[] args) { //var eval = CSScript.Evaluator.ReferenceAssemblyByNamespacompilecode.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()
