执行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 }