执行C#动态代码

执行C#动态代码

  1 using System;
  2 using System.Data;
  3 using System.Configuration;
  4 using System.Text;
  5 using System.CodeDom.Compiler;
  6 using Microsoft.CSharp;
  7 using System.Reflection;
  8 
  9 namespace EvalGuy
 10 {
 11     /// <summary>   
 12     /// 本类用来将字符串转为可执行文本并执行   
 13     /// 从别处复制,勿随意更改!   
 14     /// </summary>   
 15     public class Evaluator
 16     {
 17         #region 构造函数   
 18         /// <summary>   
 19         /// 可执行串的构造函数   
 20         /// </summary>   
 21         /// <param name="items">   
 22         /// 可执行字符串数组   
 23         /// </param>   
 24         public Evaluator(EvaluatorItem[] items)
 25         {
 26             ConstructEvaluator(items);      //调用解析字符串构造函数进行解析   
 27         }
 28         /// <summary>   
 29         /// 可执行串的构造函数   
 30         /// </summary>   
 31         /// <param name="returnType">返回值类型</param>   
 32         /// <param name="expression">执行表达式</param>   
 33         /// <param name="name">执行字符串名称</param>   
 34         public Evaluator(Type returnType, string expression, string name)
 35         {
 36             //创建可执行字符串数组   
 37             EvaluatorItem[] items = { new EvaluatorItem(returnType, expression, name) };
 38             ConstructEvaluator(items);      //调用解析字符串构造函数进行解析   
 39         }
 40         /// <summary>   
 41         /// 可执行串的构造函数   
 42         /// </summary>   
 43         /// <param name="item">可执行字符串项</param>   
 44         public Evaluator(EvaluatorItem item)
 45         {
 46             EvaluatorItem[] items = { item };//将可执行字符串项转为可执行字符串项数组   
 47             ConstructEvaluator(items);      //调用解析字符串构造函数进行解析   
 48         }
 49         /// <summary>   
 50         /// 解析字符串构造函数   
 51         /// </summary>   
 52         /// <param name="items">待解析字符串数组</param>   
 53         private void ConstructEvaluator(EvaluatorItem[] items)
 54         {
 55             //创建C#编译器实例   
 56             ICodeCompiler comp = (new CSharpCodeProvider().CreateCompiler());
 57             //编译器的传入参数   
 58             CompilerParameters cp = new CompilerParameters();
 59 
 60             cp.ReferencedAssemblies.Add("system.dll");              //添加程序集 system.dll 的引用   
 61             cp.ReferencedAssemblies.Add("system.data.dll");         //添加程序集 system.data.dll 的引用   
 62             cp.ReferencedAssemblies.Add("system.xml.dll");          //添加程序集 system.xml.dll 的引用   
 63             cp.GenerateExecutable = false;                          //不生成可执行文件   
 64             cp.GenerateInMemory = true;                             //在内存中运行   
 65 
 66             StringBuilder code = new StringBuilder();               //创建代码串   
 67                                                                     /* 
 68                                                                      * 添加常见且必须的引用字符串 
 69                                                                      */
 70             code.Append("using System; 
");
 71             code.Append("using System.Data; 
");
 72             code.Append("using System.Data.SqlClient; 
");
 73             code.Append("using System.Data.OleDb; 
");
 74             code.Append("using System.Xml; 
");
 75 
 76             code.Append("namespace EvalGuy { 
");                  //生成代码的命名空间为EvalGuy,和本代码一样   
 77 
 78             code.Append(" public class _Evaluator { 
");          //产生 _Evaluator 类,所有可执行代码均在此类中运行   
 79             foreach (EvaluatorItem item in items)               //遍历每一个可执行字符串项   
 80             {
 81                 code.AppendFormat("    public {0} {1}() ",          //添加定义公共函数代码   
 82                                   item.ReturnType.Name,             //函数返回值为可执行字符串项中定义的返回值类型   
 83                                   item.Name);                       //函数名称为可执行字符串项中定义的执行字符串名称   
 84                 code.Append("{ ");                                  //添加函数开始括号   
 85                 code.AppendFormat("return ({0});", item.Expression);//添加函数体,返回可执行字符串项中定义的表达式的值   
 86                 code.Append("}
");                                 //添加函数结束括号   
 87             }
 88             code.Append("} }");                                 //添加类结束和命名空间结束括号   
 89 
 90             //得到编译器实例的返回结果   
 91             CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString());
 92 
 93             if (cr.Errors.HasErrors)                            //如果有错误   
 94             {
 95                 StringBuilder error = new StringBuilder();          //创建错误信息字符串   
 96                 error.Append("编译有错误的表达式: ");                //添加错误文本   
 97                 foreach (CompilerError err in cr.Errors)            //遍历每一个出现的编译错误   
 98                 {
 99                     error.AppendFormat("{0}
", err.ErrorText);     //添加进错误文本,每个错误后换行   
100                 }
101                 throw new Exception("编译错误: " + error.ToString());//抛出异常   
102             }
103             Assembly a = cr.CompiledAssembly;                       //获取编译器实例的程序集   
104             _Compiled = a.CreateInstance("EvalGuy._Evaluator");     //通过程序集查找并声明 EvalGuy._Evaluator 的实例   
105         }
106         #endregion
107 
108         #region 公有成员   
109         /// <summary>   
110         /// 执行字符串并返回整型值   
111         /// </summary>   
112         /// <param name="name">执行字符串名称</param>   
113         /// <returns>执行结果</returns>   
114         public int EvaluateInt(string name)
115         {
116             return (int)Evaluate(name);
117         }
118         /// <summary>   
119         /// 执行字符串并返回字符串型值   
120         /// </summary>   
121         /// <param name="name">执行字符串名称</param>   
122         /// <returns>执行结果</returns>   
123         public string EvaluateString(string name)
124         {
125             return (string)Evaluate(name);
126         }
127         /// <summary>   
128         /// 执行字符串并返回布尔型值   
129         /// </summary>   
130         /// <param name="name">执行字符串名称</param>   
131         /// <returns>执行结果</returns>   
132         public bool EvaluateBool(string name)
133         {
134             return (bool)Evaluate(name);
135         }
136         /// <summary>   
137         /// 执行字符串并返 object 型值   
138         /// </summary>   
139         /// <param name="name">执行字符串名称</param>   
140         /// <returns>执行结果</returns>   
141         public object Evaluate(string name)
142         {
143             MethodInfo mi = _Compiled.GetType().GetMethod(name);//获取 _Compiled 所属类型中名称为 name 的方法的引用   
144             return mi.Invoke(_Compiled, null);                  //执行 mi 所引用的方法   
145         }
146         #endregion
147 
148         #region 静态成员   
149         /// <summary>   
150         /// 执行表达式并返回整型值   
151         /// </summary>   
152         /// <param name="code">要执行的表达式</param>   
153         /// <returns>运算结果</returns>   
154         static public int EvaluateToInteger(string code)
155         {
156             Evaluator eval = new Evaluator(typeof(int), code, staticMethodName);//生成 Evaluator 类的对像   
157             return (int)eval.Evaluate(staticMethodName);                        //执行并返回整型数据   
158         }
159         /// <summary>   
160         /// 执行表达式并返回字符串型值   
161         /// </summary>   
162         /// <param name="code">要执行的表达式</param>   
163         /// <returns>运算结果</returns>   
164         static public string EvaluateToString(string code)
165         {
166             Evaluator eval = new Evaluator(typeof(string), code, staticMethodName);//生成 Evaluator 类的对像   
167             return (string)eval.Evaluate(staticMethodName);                     //执行并返回字符串型数据   
168         }
169         /// <summary>   
170         /// 执行表达式并返回布尔型值   
171         /// </summary>   
172         /// <param name="code">要执行的表达式</param>   
173         /// <returns>运算结果</returns>   
174         static public bool EvaluateToBool(string code)
175         {
176             Evaluator eval = new Evaluator(typeof(bool), code, staticMethodName);//生成 Evaluator 类的对像   
177             return (bool)eval.Evaluate(staticMethodName);                       //执行并返回布尔型数据   
178         }
179         /// <summary>   
180         /// 执行表达式并返回 object 型值   
181         /// </summary>   
182         /// <param name="code">要执行的表达式</param>   
183         /// <returns>运算结果</returns>   
184         static public object EvaluateToObject(string code)
185         {
186             Evaluator eval = new Evaluator(typeof(object), code, staticMethodName);//生成 Evaluator 类的对像   
187             return eval.Evaluate(staticMethodName);                             //执行并返回 object 型数据   
188         }
189         #endregion
190 
191         #region 私有成员   
192         /// <summary>   
193         /// 静态方法的执行字符串名称   
194         /// </summary>   
195         private const string staticMethodName = "__foo";
196         /// <summary>   
197         /// 用于动态引用生成的类,执行其内部包含的可执行字符串   
198         /// </summary>   
199         object _Compiled = null;
200         #endregion
201     }
202     /// <summary>   
203     /// 可执行字符串项(即一条可执行字符串)   
204     /// </summary>   
205     public class EvaluatorItem
206     {
207         /// <summary>   
208         /// 返回值类型   
209         /// </summary>   
210         public Type ReturnType;
211         /// <summary>   
212         /// 执行表达式   
213         /// </summary>   
214         public string Expression;
215         /// <summary>   
216         /// 执行字符串名称   
217         /// </summary>   
218         public string Name;
219         /// <summary>   
220         /// 可执行字符串项构造函数   
221         /// </summary>   
222         /// <param name="returnType">返回值类型</param>   
223         /// <param name="expression">执行表达式</param>   
224         /// <param name="name">执行字符串名称</param>   
225         public EvaluatorItem(Type returnType, string expression, string name)
226         {
227             ReturnType = returnType;
228             Expression = expression;
229             Name = name;
230         }
231     }
232 }
View Code
原文地址:https://www.cnblogs.com/wang0020/p/10239472.html