随笔 - 435  文章 - 0  评论 - 111  阅读 - 62万 

从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();

 

posted on   Gu  阅读(420)  评论(0编辑  收藏  举报
编辑推荐:
· 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 隐藏行
点击右上角即可分享
微信分享提示