广告
返回顶部
首页 > 资讯 > 精选 >C#如何实现动态执行字符串脚本
  • 917
分享到

C#如何实现动态执行字符串脚本

2023-07-05 17:07:46 917人浏览 薄情痞子
摘要

这篇文章主要介绍了C#如何实现动态执行字符串脚本的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#如何实现动态执行字符串脚本文章都会有所收获,下面我们一起来看看吧。先来代码using System;u

这篇文章主要介绍了C#如何实现动态执行字符串脚本的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#如何实现动态执行字符串脚本文章都会有所收获,下面我们一起来看看吧。

先来代码

using System;using System.Data;using System.Configuration;using System.Text;using System.CodeDom.Compiler;using Microsoft.CSharp;using System.Reflection;using System.Collections.Generic;namespace 检漏仪上位机{    /// <summary>    /// 本类用来将字符串转为可执行文本并执行    /// 从别处复制,勿随意更改!    /// </summary>    public class Evaluator    {        #region 构造函数        /// <summary>        /// 可执行串的构造函数        /// </summary>        /// <param name="items">        /// 可执行字符串数组        /// </param>        public Evaluator(EvaluatorItem[] items, Dictionary<string, string> listAssemblies = null)        {            ConstructEvaluator(items, listAssemblies);      //调用解析字符串构造函数进行解析        }        /// <summary>        /// 可执行串的构造函数        /// </summary>        /// <param name="returnType">返回值类型</param>        /// <param name="expression">执行表达式</param>        /// <param name="name">执行字符串名称</param>        public Evaluator(Type returnType, string expression, string name, Dictionary<string, string> listAssemblies = null)        {            //创建可执行字符串数组            EvaluatorItem[] items = { new EvaluatorItem(returnType, expression, name) };            ConstructEvaluator(items, listAssemblies);      //调用解析字符串构造函数进行解析        }        public Evaluator(string allCode, string _namespace, string _class, List<string> listAssemblies = null)        {            ConstructEvaluatorByAllCode(allCode, _namespace, _class, listAssemblies);      //调用解析字符串构造函数进行解析        }        /// <summary>        /// 可执行串的构造函数        /// </summary>        /// <param name="item">可执行字符串项</param>        public Evaluator(EvaluatorItem item, Dictionary<string, string> listAssemblies = null)        {            EvaluatorItem[] items = { item };//将可执行字符串项转为可执行字符串项数组            ConstructEvaluator(items, listAssemblies);      //调用解析字符串构造函数进行解析        }        /// <summary>        /// 解析字符串构造函数        /// </summary>        /// <param name="items">待解析字符串数组</param>        private void ConstructEvaluator(EvaluatorItem[] items, Dictionary<string, string> listAssemblies = null)        {            //创建C#编译器实例            ICodeCompiler comp = (new CSharpcodeProvider().CreateCompiler());            //编译器的传入参数            CompilerParameters cp = new CompilerParameters();            cp.ReferencedAssemblies.Add("system.dll");              //添加程序集 system.dll 的引用            cp.ReferencedAssemblies.Add("system.data.dll");         //添加程序集 system.data.dll 的引用            cp.ReferencedAssemblies.Add("system.xml.dll");          //添加程序集 system.xml.dll 的引用            cp.ReferencedAssemblies.Add("System.windows.FORMs.dll");          //添加程序集 system.xml.dll 的引用            cp.GenerateExecutable = false;                          //不生成可执行文件            cp.GenerateInMemory = true;                             //在内存中运行            StringBuilder code = new StringBuilder();               //创建代码串            if (listAssemblies != null)            {                foreach (var item in listAssemblies)                {                    cp.ReferencedAssemblies.Add(item.Key);              //添加程序集 引用                    code.Append("using "+item.Value + "; \n");                }            }                        code.Append("using System; \n");            code.Append("using System.Data; \n");            code.Append("using System.Data.sqlClient; \n");            code.Append("using System.Data.OleDb; \n");            code.Append("using System.Xml; \n");            code.Append("using System.Windows.Forms; \n");            code.Append("namespace EvalGuy { \n");                  //生成代码的命名空间为EvalGuy,和本代码一样            code.Append(" public class _Evaluator { \n");          //产生 _Evaluator 类,所有可执行代码均在此类中运行            foreach (EvaluatorItem item in items)               //遍历每一个可执行字符串项            {                code.AppendFormat("    public {0} {1}() ",          //添加定义公共函数代码                                item.ReturnType == null ? "void" : item.ReturnType.Name,             //函数返回值为可执行字符串项中定义的返回值类型                                  item.Name);                       //函数名称为可执行字符串项中定义的执行字符串名称                code.Append("{ ");                                  //添加函数开始括号                if (item.ReturnType != null)                    code.AppendFormat("return ({0});", item.Expression);//添加函数体,返回可执行字符串项中定义的表达式的值                else                {                    code.Append(item.Expression);//添加函数体,返回可执行字符串项中定义的表达式的值                }                code.Append("}\n");                                 //添加函数结束括号            }            code.Append("} }");                                 //添加类结束和命名空间结束括号            //得到编译器实例的返回结果            CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString());            if (cr.Errors.HasErrors)                            //如果有错误            {                StringBuilder error = new StringBuilder();          //创建错误信息字符串                error.Append("编译有错误的表达式: ");                //添加错误文本                foreach (CompilerError err in cr.Errors)            //遍历每一个出现的编译错误                {                    error.AppendFormat("{0}\n", err.ErrorText);     //添加进错误文本,每个错误后换行                }                throw new Exception("编译错误: " + error.ToString());//抛出异常            }            Assembly a = cr.CompiledAssembly;                       //获取编译器实例的程序集            _Compiled = a.CreateInstance("EvalGuy._Evaluator");     //通过程序集查找并声明 EvalGuy._Evaluator 的实例        }        private void ConstructEvaluatorByAllCode(string allcode, string _namespace, string _class, List<string> listAssemblies)        {            if (listAssemblies == null)            {                listAssemblies = new List<string>();            }            //创建C#编译器实例            ICodeCompiler comp = (new CSharpCodeProvider().CreateCompiler());            //编译器的传入参数            CompilerParameters cp = new CompilerParameters();            if (!listAssemblies.Contains("system.dll"))            {                listAssemblies.Add("system.dll");                listAssemblies.Add("system.data.dll");                listAssemblies.Add("system.xml.dll");            }            foreach (var item in listAssemblies)            {                cp.ReferencedAssemblies.Add(item);            }            cp.GenerateExecutable = false;                          //不生成可执行文件            cp.GenerateInMemory = true;                             //在内存中运行            //得到编译器实例的返回结果            CompilerResults cr = comp.CompileAssemblyFromSource(cp, allcode);            if (cr.Errors.HasErrors)                            //如果有错误            {                StringBuilder error = new StringBuilder();          //创建错误信息字符串                error.Append("编译有错误的表达式: ");                //添加错误文本                foreach (CompilerError err in cr.Errors)            //遍历每一个出现的编译错误                {                    error.AppendFormat("{0}\n", err.ErrorText);     //添加进错误文本,每个错误后换行                }                throw new Exception("编译错误: " + error.ToString());//抛出异常            }            Assembly a = cr.CompiledAssembly;                       //获取编译器实例的程序集            _Compiled = a.CreateInstance($"{_namespace}.{_class}");     //通过程序集查找并声明 EvalGuy._Evaluator 的实例        }        #endregion        #region 公有成员        /// <summary>        /// 执行字符串并返回整型值        /// </summary>        /// <param name="name">执行字符串名称</param>        /// <returns>执行结果</returns>        public int EvaluateInt(string name)        {            return (int)Evaluate(name);        }        /// <summary>        /// 执行字符串并返回字符串型值        /// </summary>        /// <param name="name">执行字符串名称</param>        /// <returns>执行结果</returns>        public string EvaluateString(string name)        {            return (string)Evaluate(name);        }        /// <summary>        /// 执行字符串并返回布尔型值        /// </summary>        /// <param name="name">执行字符串名称</param>        /// <returns>执行结果</returns>        public bool EvaluateBool(string name)        {            return (bool)Evaluate(name);        }        /// <summary>        /// 执行字符串并返 object 型值        /// </summary>        /// <param name="name">执行字符串名称</param>        /// <returns>执行结果</returns>        public object Evaluate(string name)        {            MethodInfo mi = _Compiled.GetType().GetMethod(name);//获取 _Compiled 所属类型中名称为 name 的方法的引用            return mi.Invoke(_Compiled, null);                  //执行 mi 所引用的方法        }        #endregion        #region 静态成员        /// <summary>        /// 执行表达式并返回整型值        /// </summary>        /// <param name="code">要执行的表达式</param>        /// <param name="listAssemblies">需要引用到类库,key:dll名称,value:命名空间名称</param>        /// <returns>运算结果</returns>        static public int EvaluateToInteger(string code, Dictionary<string, string> listAssemblies = null)        {            Evaluator eval = new Evaluator(typeof(int), code, staticMethodName, listAssemblies);//生成 Evaluator 类的对像            return (int)eval.Evaluate(staticMethodName);                        //执行并返回整型数据        }        /// <summary>        /// 执行表达式并返回字符串型值        /// </summary>        /// <param name="code">要执行的表达式</param>        /// <param name="listAssemblies">需要引用到类库,key:dll名称,value:命名空间名称</param>        /// <returns>运算结果</returns>        static public string EvaluateToString(string code, Dictionary<string, string> listAssemblies = null)        {            Evaluator eval = new Evaluator(typeof(string), code, staticMethodName, listAssemblies);//生成 Evaluator 类的对像            return (string)eval.Evaluate(staticMethodName);                     //执行并返回字符串型数据        }        /// <summary>        /// 执行表达式并返回布尔型值        /// </summary>        /// <param name="code">要执行的表达式</param>        /// <param name="listAssemblies">需要引用到类库,key:dll名称,value:命名空间名称</param>        /// <returns>运算结果</returns>        static public bool EvaluateToBool(string code, Dictionary<string, string> listAssemblies = null)        {            Evaluator eval = new Evaluator(typeof(bool), code, staticMethodName, listAssemblies);//生成 Evaluator 类的对像            return (bool)eval.Evaluate(staticMethodName);                       //执行并返回布尔型数据        }        /// <summary>        /// 执行表达式并返回 object 型值        /// </summary>        /// <param name="code">要执行的表达式</param>        /// <param name="listAssemblies">需要引用到类库,key:dll名称,value:命名空间名称</param>        /// <returns>运算结果</returns>        static public object EvaluateToObject(string code, Dictionary<string, string> listAssemblies = null)        {            Evaluator eval = new Evaluator(typeof(object), code, staticMethodName, listAssemblies);//生成 Evaluator 类的对像            return eval.Evaluate(staticMethodName);                             //执行并返回 object 型数据        }        /// <summary>        /// 执行一个无返回式的代码        /// </summary>        /// <param name="code"></param>        /// <param name="listAssemblies">需要引用到类库,key:dll名称,value:命名空间名称</param>        static public void EvaluateToVoid(string code, Dictionary<string, string> listAssemblies = null)        {            Evaluator eval = new Evaluator(null, code, staticMethodName, listAssemblies);//生成 Evaluator 类的对像            eval.Evaluate(staticMethodName);                             //执行并返回 object 型数据        }        /// <summary>        /// 执行一个全代码        /// </summary>        /// <param name="code">全代码,包含命名空间引用,命名空间声明,类声明,函数声明等</param>        /// <param name="_namespace"></param>        /// <param name="_class"></param>        /// <param name="methodName">函数</param>        /// <param name="listAssemblies">需要引用到类库</param>        public static void EvaluateByAllCode(string code, string _namespace, string _class, string methodName, List<string> listAssemblies = null)        {            Evaluator eval = new Evaluator(code, _namespace, _class, listAssemblies);//生成 Evaluator 类的对像            eval.Evaluate(methodName);        }        #endregion        #region 私有成员        /// <summary>        /// 静态方法的执行字符串名称        /// </summary>        private const string staticMethodName = "__foo";        /// <summary>        /// 用于动态引用生成的类,执行其内部包含的可执行字符串        /// </summary>        object _Compiled = null;        #endregion    }    /// <summary>    /// 可执行字符串项(即一条可执行字符串)    /// </summary>    public class EvaluatorItem    {        /// <summary>        /// 返回值类型        /// </summary>        public Type ReturnType;        /// <summary>        /// 执行表达式        /// </summary>        public string Expression;        /// <summary>        /// 执行字符串名称        /// </summary>        public string Name;        /// <summary>        /// 可执行字符串项构造函数        /// </summary>        /// <param name="returnType">返回值类型</param>        /// <param name="expression">执行表达式</param>        /// <param name="name">执行字符串名称</param>        public EvaluatorItem(Type returnType, string expression, string name)        {            ReturnType = returnType;            Expression = expression;            Name = name;        }    }}

调用一个无返回值的代码,显示一个提示框

Evaluator.EvaluateToVoid("MessageBox.Show(\"Test\");",new Dictionary<string, string>() { { "System.Windows.Forms.dll", "System.Windows.Forms" } });

调用一个计算返回整型

Evaluator.EvaluateToInteger("1+2*3");

调用一个全代码

string str = @"using System;namespace a{     public class b    {        public  void c()        {            Console.WriteLine(1);        }    }}";Evaluator.EvaluateByAllCode(str, "a", "b", "c");

功能就这么多

关于“C#如何实现动态执行字符串脚本”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“C#如何实现动态执行字符串脚本”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网精选频道。

--结束END--

本文标题: C#如何实现动态执行字符串脚本

本文链接: https://www.lsjlt.com/news/353581.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C#如何实现动态执行字符串脚本
    这篇文章主要介绍了C#如何实现动态执行字符串脚本的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#如何实现动态执行字符串脚本文章都会有所收获,下面我们一起来看看吧。先来代码using System;u...
    99+
    2023-07-05
  • shell脚本实现字符串的动态替换方法
    目录背景代码使用示例用shell实现某行字符串的替换背景 我们有时候需要完成字符串的多组替换,比如需要完成以下替换 将“小草”替换为“真是让人印象深刻”将“小狗...
    99+
    2022-10-24
  • Redis 字符串实现:简单动态字符串-SDS与C字符串的区别
    2.1 SDS的定义 struct { //buf中已使用的字节数,等于SDS所保存字符串的长度 int len; //buf中未使用的字节长度 int free; //字节数组,用于保存...
    99+
    2020-09-07
    Redis 字符串实现:简单动态字符串-SDS与C字符串的区别
  • C#如何实现字符串搜索
    小编给大家分享一下C#如何实现字符串搜索,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、正则表达式简介正则表达式提供了功能强大、灵活而又高效的方法来处理文本。正...
    99+
    2023-06-18
  • Shell脚本如何实现查找字符串中某字符最后出现的位置
    这篇文章将为大家详细讲解有关Shell脚本如何实现查找字符串中某字符最后出现的位置,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。需要对字符串查找其中某个字符最后出现的位置,这个在PHP (strrpos)...
    99+
    2023-06-09
  • C++如何实现回文子字符串
    这篇文章主要介绍“C++如何实现回文子字符串”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++如何实现回文子字符串”文章能帮助大家解决问题。Palindromic Substrings 回文子字符...
    99+
    2023-06-19
  • C语言如何动态分配二维字符串数组
    这篇文章给大家分享的是有关C语言如何动态分配二维字符串数组的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。动态分配一个二维字符串数组(1) 分配可能不连续的内存申请char**pps8Output = (char ...
    99+
    2023-06-25
  • c语言如何实现字符串反转
    C语言可以通过循环遍历字符串并交换字符的位置来实现字符串的反转。具体步骤如下:1. 首先,定义一个指向字符串的指针。2. 使用`st...
    99+
    2023-09-12
    c语言
  • C语言如何实现字符串替换
    在C语言中可以通过循环遍历字符串的每个字符,然后判断是否需要替换,如果需要替换则使用新的字符替换原字符。下面是一个示例代码,实现了字...
    99+
    2023-08-24
    C语言
  • 如何编写Shell脚本实现快速去除字符串中的空格
    这篇文章主要讲解了“如何编写Shell脚本实现快速去除字符串中的空格”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何编写Shell脚本实现快速去除字符串中的空格”吧!效果如下图所示,图上半...
    99+
    2023-06-09
  • c语言中如何实现逆序字符串
    这篇文章主要介绍了c语言中如何实现逆序字符串,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。使用指针逆序字符串思路:给两个指针,left放在字符串左侧,right放在最后一个有...
    99+
    2023-06-26
  • 如何实现IP动态切换bat脚本
    这篇文章将为大家详细讲解有关如何实现IP动态切换bat脚本,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。新建"IP切换脚本.bat"文件,将下列代码复制进去,保存,并加入启动项,这样每...
    99+
    2023-06-08
  • 使用Zabbix实现动态执行监控采集脚本的原理是什么
    使用Zabbix实现动态执行监控采集脚本的原理是什么?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。实现原理:使用文件服务器统一存放和管理监控脚本,在zabbix...
    99+
    2023-06-06
  • 如何使用C语言实现字符串逆序
    本篇内容介绍了“如何使用C语言实现字符串逆序”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!编写一个函数 r...
    99+
    2022-10-19
  • LINUX下如何用CRON实现定时执行脚本
    这篇文章主要为大家展示了“LINUX下如何用CRON实现定时执行脚本”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“LINUX下如何用CRON实现定时执行脚本”这...
    99+
    2022-10-18
  • 如何实现一键自动更改本机IP地址的BAT执行脚本
    这篇文章给大家分享的是有关如何实现一键自动更改本机IP地址的BAT执行脚本的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。请把复制下面的脚本,另存为.bat文件,把其中的子网掩码,网关,IP,DNS等信息修改成你的...
    99+
    2023-06-08
  • 如何使用setimmediate实现可伸缩执行的脚本
    这篇文章主要介绍“如何使用setimmediate实现可伸缩执行的脚本”,在日常操作中,相信很多人在如何使用setimmediate实现可伸缩执行的脚本问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操...
    99+
    2022-10-19
  • jenkins如何实现shell脚本化定时执行任务
    这篇文章将为大家详细讲解有关jenkins如何实现shell脚本化定时执行任务,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。开发需求socket连接的auction拍卖jar包服务更新重启前半小时切走ng...
    99+
    2023-06-26
  • C#使用第三方组件实现动态解析和求值字符串表达式
    目录介绍1、Z.Expressions.Eval 表达式解析2、NReco.LambdaParser 表达式解析3、DynamicExpresso 表达式解析4、SQL条件语句的正则...
    99+
    2022-11-13
  • 如何通过脚本实现数据动态更新
    在数据填报的场景中,常常会遇到根据条件动态更新数据的需求,例如:在条件 A 下将页面所有数据插入到数据库表中,而在条件 B 下则将页面中做了修改的数据更新到数据库表中。遇到这种需求,脑海中的第一个想法就是:存储过程更新、或者 java 代码...
    99+
    2023-06-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作