返回顶部
首页 > 资讯 > 精选 >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://lsjlt.com/news/353581.html(转载时请注明来源链接)

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

猜你喜欢
  • C#如何实现动态执行字符串脚本
    这篇文章主要介绍了C#如何实现动态执行字符串脚本的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#如何实现动态执行字符串脚本文章都会有所收获,下面我们一起来看看吧。先来代码using System;u...
    99+
    2023-07-05
  • shell脚本实现字符串的动态替换方法
    目录背景代码使用示例用shell实现某行字符串的替换背景 我们有时候需要完成字符串的多组替换,比如需要完成以下替换 将“小草”替换为“真是让人印象深刻”将“小狗...
    99+
    2024-04-02
  • Redis 字符串实现:简单动态字符串-SDS与C字符串的区别
    2.1 SDS的定义 struct { //buf中已使用的字节数,等于SDS所保存字符串的长度 int len; //buf中未使用的字节长度 int free; //字节数组,用于保存...
    99+
    2020-09-07
    Redis 字符串实现:简单动态字符串-SDS与C字符串的区别
  • c#动态执行脚本的方式有哪些
    这篇文章主要介绍“c#动态执行脚本的方式有哪些”,在日常操作中,相信很多人在c#动态执行脚本的方式有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”c#动态执行脚本的方式有哪些”的疑惑有所帮助!接下来,请跟...
    99+
    2023-07-05
  • c#动态执行脚本的3种方式详解
    目录1.使用Roslyn编译器2.使用IronPython或IronRuby3.使用JavaScript引擎在C#中,可以使用一些第三方库或内置类库实现动态执行脚本的功能。以下是几个...
    99+
    2023-05-14
    c#动态执行脚本 c#动态执行
  • Shell脚本实现简单分割字符串
    我们有这样一个字符串: info='abcd;efgh' 现在想获取abcd和efgh,我们可以简单地用cut工具来获取: fstr=`echo $info | cut -d ; -f 1` sst...
    99+
    2022-06-04
    字符串 脚本 简单
  • C#中如何构建动态SQL查询字符串
    在C#中可以使用StringBuilder类来构建动态SQL查询字符串。以下是一个示例: using System.Text; S...
    99+
    2024-04-28
    C#
  • C#如何实现字符串搜索
    小编给大家分享一下C#如何实现字符串搜索,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、正则表达式简介正则表达式提供了功能强大、灵活而又高效的方法来处理文本。正...
    99+
    2023-06-18
  • 如何执行字符串的PHP代码
    最近因项目需要,引出一个议题:如何执行字符串的php代码(php和html混写)。注:传统情况下,php代码存储在文件中,直接运行文件即可。以下讨论的情况是,如果php代码是从数据库中获取到,那么要如何运行...
    99+
    2024-04-02
  • Shell脚本如何实现查找字符串中某字符最后出现的位置
    这篇文章将为大家详细讲解有关Shell脚本如何实现查找字符串中某字符最后出现的位置,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。需要对字符串查找其中某个字符最后出现的位置,这个在PHP (strrpos)...
    99+
    2023-06-09
  • C++如何实现回文子字符串
    这篇文章主要介绍“C++如何实现回文子字符串”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++如何实现回文子字符串”文章能帮助大家解决问题。Palindromic Substrings 回文子字符...
    99+
    2023-06-19
  • PHP如何对字符串执行rot13转换
    这篇文章将为大家详细讲解有关PHP如何对字符串执行rot13转换,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。PHP中执行ROT13字符串转换指南 简介 ROT13 是一种简单的字母替换密码,用来对字符串...
    99+
    2024-04-02
  • 如何实现IP动态切换bat脚本
    这篇文章将为大家详细讲解有关如何实现IP动态切换bat脚本,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。新建"IP切换脚本.bat"文件,将下列代码复制进去,保存,并加入启动项,这样每...
    99+
    2023-06-08
  • C语言如何动态分配二维字符串数组
    这篇文章给大家分享的是有关C语言如何动态分配二维字符串数组的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。动态分配一个二维字符串数组(1) 分配可能不连续的内存申请char**pps8Output = (char ...
    99+
    2023-06-25
  • Linux 使用shell脚本处理字符串的实现
    1. 截取字符串的前8位 expr substr "$string" 1 8 echo $string | awk '{print substr(,1,8)}' echo $string | cut -c...
    99+
    2022-06-04
    shell处理字符串 shell字符串处理
  • c语言如何实现字符串反转
    C语言可以通过循环遍历字符串并交换字符的位置来实现字符串的反转。具体步骤如下:1. 首先,定义一个指向字符串的指针。2. 使用`st...
    99+
    2023-09-12
    c语言
  • C语言如何实现字符串替换
    在C语言中可以通过循环遍历字符串的每个字符,然后判断是否需要替换,如果需要替换则使用新的字符替换原字符。下面是一个示例代码,实现了字...
    99+
    2023-08-24
    C语言
  • c语言如何实现字符串复制
    在C语言中,可以使用strcpy()函数来实现字符串复制。具体实现方法如下: #include <stdio.h> #i...
    99+
    2024-04-09
    c语言
  • LINUX下如何用CRON实现定时执行脚本
    这篇文章主要为大家展示了“LINUX下如何用CRON实现定时执行脚本”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“LINUX下如何用CRON实现定时执行脚本”这...
    99+
    2024-04-02
  • Shell脚本实现查找字符串中某字符最后出现的位置
    需要对字符串查找其中某个字符最后出现的位置,这个在PHP (strrpos)或者Perl (rindex)里面都有现成函数可用的功能,在Shell里面居然一时想不出个道道来。在论坛上发贴也没人解答(不知道是...
    99+
    2022-06-04
    字符串 脚本 字符
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作