从Nuget安装
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
如果语法有错误,就会在下面的textbox显示编译错误
/// <summary> /// 多运行几次,就过100M内存了.不定期GC后也要占用50M /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnRun_Click(object sender, EventArgs e) { txtErr.Text = ""; var text = txtScript.Text; var tree = SyntaxFactory.ParseSyntaxTree(text); var systemReference = MetadataReference.CreateFromFile(typeof(object).Assembly.Location); var compilation = CSharpCompilation.Create("calc.dll") .AddSyntaxTrees(tree) .AddReferences(systemReference) .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); Assembly compiledAssembly; //string outputPath = System.Windows.Forms.Application.StartupPath + "\\PlugIn\\" + "calc.dll"; //calc.dll保存在内存,没保存在文件 using (var stream = new MemoryStream()) { var compileResult = compilation.Emit(stream); //var compileResult = compilation.Emit(outputPath);//假如保存到c盘,需要权限 //用文件的话,再Emit的时候,会出现calc.dll”正由另一进程使用,因此该进程无法访问此文件。” if (!compileResult.Success) { foreach (var item in compilation.GetDiagnostics()) { txtErr.Text+= item.GetMessage() + Environment.NewLine; } MessageBox.Show("编译失败"); return; } compiledAssembly = Assembly.Load(stream.GetBuffer()); //compiledAssembly = Assembly.LoadFile(outputPath); } try { var calculatorClass = compiledAssembly.GetType("Calculator"); if(calculatorClass!=null) { var evaluateMethod = calculatorClass.GetMethod("Evaluate"); var result = evaluateMethod.Invoke(null, null).ToString(); Console.WriteLine(result); MessageBox.Show(result); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } //占用30M内存 private void btnSnippet_Click(object sender, EventArgs e) { try { var scriptState = CSharpScript.RunAsync<int>("if(DateTime.Now.Hour<12) return 13+2*5;else return 0;", ScriptOptions.Default.AddImports("System","System.IO")); MessageBox.Show(scriptState.Result.ReturnValue.ToString()); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
对于Microsoft.CodeAnalysis,来运行一小段代码,没有用到其他依赖的话, 还是太重了.因为它要引入多个DLL,启动时间在我的机器上要几秒,占用的内存还多, 可以考虑用其他的
比如ClearScript和Jint 微软自家的.Net下的JavaScript引擎--- ClearScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | //https://microsoft.github.io/ClearScript/Examples/Examples.html using (var engine = new V8ScriptEngine()) { engine.DocumentSettings.AccessFlags = Microsoft.ClearScript.DocumentAccessFlags.EnableFileLoading; engine.DefaultAccess = Microsoft.ClearScript.ScriptAccess.Full; // 这两行是为了允许加载js文件\ engine.AddHostType( "Console" , typeof(Console)); engine.Execute( "Console.WriteLine('{0} is an interesting number.', Math.PI)" ); // expose a host object engine.AddHostObject( "random" , new Random()); engine.Execute( "Console.WriteLine(random.NextDouble())" ); //添加主机的模式。以便js可以调用主机这边的一些c#类型或、对象 /* engine.AddHostType("tt", typeof(test));*/ // execute 开始执行代码 , 里面填写js代码 engine.Execute(@"var a = 3 ; var b = 5 ; function add(a, b) { return a + b; } var result = add(a, b) Console.WriteLine(result);"); var result =engine.Evaluate( "2>1 && 3>4" ); var result1= engine.Evaluate(Expression); return (bool)result1; } |
另外的Jint 也很优秀, 支持NETSTANDARD2.0, 依赖更少一些
var engine = new Jint.Engine(); var result =engine.Execute(Expression).GetCompletionValue().AsBoolean();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
2016-12-16 Excel Note
2011-12-16 NPOI 隐藏行