代码文档模型CodeDom命名空间下主要有两个,很明显第一个代码逻辑分析,第二个负责代码的编译
using System.CodeDom; using System.CodeDom.Compiler;
一、代码逻辑
1、CodeNamespace创建命名空间
CodeNamespace nspace=new CodeNamespace("Practice.MyNamespace")//创建命名空间 nspace.Imports.Add(new CodeNamespaceImport("System"));//引入程序命名空间:using System; //nspace.Types 命名空间中所含类的集合,使用add添加
2、CodeTypeDeclaration类定义
CodeTypeDeclaration helloword = new CodeTypeDeclaration("HelloWord");//类型Class声明 helloword.Attributes = MemberAttributes.Public;//public //helloword.Members.AddRange(new CodeTypeMember[] { method, main });//添加方法到clss
3、CodeMemberMethod/CodeEntryPointMethod方法
CodeMemberMethod method = new CodeMemberMethod();//方法声明; method.Name = "SayHello";// 方法名 method.Attributes = MemberAttributes.Public | MemberAttributes.Final;//属性 method.ReturnType = new CodeTypeReference(typeof(string));//返回类型 method.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression("Hello from code!")));
//方法体,只有一句返回语句return "Hello from code!"; CodeEntryPointMethod main = new CodeEntryPointMethod();//主方法Main main.Statements.Add(new CodeVariableDeclarationStatement("HelloWord", "hw", new CodeObjectCreateExpression("HelloWord", new CodeExpression[] { })));//变量声明:HelloWord hw = new HelloWord();
4、CodeMethodInvokeExpression表达式
CodeMethodInvokeExpression methodinvoke =
new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("hw"), "SayHello", new CodeExpression[] { }); main.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"), "WriteLine", methodinvoke)); main.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"), "Read"));
//两个方法调用:System.Console.WriteLine(hw.SayHello());
二、编译
System.CodeDom.Compiler常用类
CodeDomProvider创建编译器
CodeDomProvider provider = CodeDomProvider.CreateProvider("VisualBasic"); CodeDomProvider provider = CodeDomProvider.CreateProvider("C#");
CompilerParameters编译器参数
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll"); //添加程序集 system.dll 的引用 cp.GenerateExecutable = false; //不生成可执行文件 cp.GenerateInMemory = true; //在内存中运行
CompilerResults编译结果
//得到编译器实例的返回结果 CompilerResults cr = provider.CompileAssemblyFromSource(cp, code.ToString())
cr.Errors //CompilerError集合、所有编译错误 cr.CompiledAssembly //Assembly、 获取编译结果的程序集
示例一
using System; using System.CodeDom; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Practice.CodeDom.Compiler { class Program { static void Main(string[] args) { Program pro = new Program(); CodeNamespace nspace = pro.CreateCodeDomHelloDemo(); Console.WriteLine(pro.GengerCode(nspace)); string filename = "HelloWorld.exe"; CompilerResults result = pro.Execute(nspace, filename); if (result.Errors.HasErrors)//是否存在错误; { for (int i = 0; i < result.Output.Count; i++) Console.WriteLine(result.Output[i]); for (int i = 0; i < result.Errors.Count; i++) Console.WriteLine(i.ToString() + ": " + result.Errors[i].ToString()); } else { System.Diagnostics.Process.Start(filename);//这里比较懒,不想动手去自己打开,呵呵; } Console.Read(); } public CodeNamespace CreateCodeDomHelloDemo() { CodeMemberMethod method = new CodeMemberMethod();//方法声明; method.Name = "SayHello";// 方法名 method.Attributes = MemberAttributes.Public | MemberAttributes.Final;//属性 method.ReturnType = new CodeTypeReference(typeof(string));//返回类型 method.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression("Hello from code!")));//方法体,只有一句返回语句return "Hello from code!"; CodeEntryPointMethod main = new CodeEntryPointMethod();//主方法Main main.Statements.Add(new CodeVariableDeclarationStatement("HelloWord", "hw", new CodeObjectCreateExpression("HelloWord", new CodeExpression[] { })));//变量声明:HelloWord hw = new HelloWord(); CodeMethodInvokeExpression methodinvoke = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("hw"), "SayHello", new CodeExpression[] { }); main.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"), "WriteLine", methodinvoke)); main.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"), "Read"));//两个方法调用:System.Console.WriteLine(hw.SayHello()); CodeTypeDeclaration helloword = new CodeTypeDeclaration("HelloWord");//类型Class声明 helloword.Attributes = MemberAttributes.Public; helloword.Members.AddRange(new CodeTypeMember[] { method, main });//添加方法到clss CodeNamespace nspace = new CodeNamespace("HelloDemo1");//命名空间声明 nspace.Imports.Add(new CodeNamespaceImport("System"));//引入程序命名空间:using System; nspace.Types.Add(helloword);// return nspace; } public string GengerCode(CodeNamespace nspace) { StringBuilder sb = new StringBuilder(); System.IO.StringWriter sw = new System.IO.StringWriter(sb); CodeGeneratorOptions geneOptions = new CodeGeneratorOptions();//代码生成选项 geneOptions.BlankLinesBetweenMembers = false; geneOptions.BracingStyle = "C"; geneOptions.ElseOnClosing = true; geneOptions.IndentString = " "; CodeDomProvider.GetCompilerInfo("c#").CreateProvider().GenerateCodeFromNamespace(nspace, sw, geneOptions);//代码生成 sw.Close(); return sb.ToString(); } public CompilerResults Execute(CodeNamespace nspace, string filename) { CodeCompileUnit unit = new CodeCompileUnit();//code编译单元 unit.Namespaces.Add(nspace); CodeDomProvider provider = CodeDomProvider.CreateProvider("C#"); CompilerParameters options = new CompilerParameters();// options.GenerateInMemory = false;//是否在内存中生成; options.IncludeDebugInformation = true;// 包含调试信息; options.ReferencedAssemblies.Add("System.dll"); options.OutputAssembly = filename; if (System.IO.Path.GetExtension(filename).ToLower() == ".exe") { options.GenerateExecutable = true;//true为可执行exe,false:dll } else { options.GenerateExecutable = false;//true为可执行exe,false:dll } return provider.CompileAssemblyFromDom(options, unit);//编译程序集 } } }
示例二
using System; using System.Data; using System.Configuration; using System.Text; using System.CodeDom.Compiler; using Microsoft.CSharp; using System.Reflection; namespace Practice.Common { /// <summary> /// 本类用来将字符串转为可执行文本并执行 /// </summary> public class DynamicEvaluator { #region 构造函数 /// <summary> /// 可执行串的构造函数 /// </summary> /// <param name="items"> /// 可执行字符串数组 /// </param> public DynamicEvaluator(EvaluatorItem[] items) { ConstructEvaluator(items); //调用解析字符串构造函数进行解析 } /// <summary> /// 可执行串的构造函数 /// </summary> /// <param name="returnType">返回值类型</param> /// <param name="expression">执行表达式</param> /// <param name="name">执行字符串名称</param> public DynamicEvaluator(Type returnType, string expression, string name) { //创建可执行字符串数组 EvaluatorItem[] items = { new EvaluatorItem(returnType, expression, name) }; ConstructEvaluator(items); //调用解析字符串构造函数进行解析 } /// <summary> /// 可执行串的构造函数 /// </summary> /// <param name="item">可执行字符串项</param> public DynamicEvaluator(EvaluatorItem item) { EvaluatorItem[] items = { item };//将可执行字符串项转为可执行字符串项数组 ConstructEvaluator(items); //调用解析字符串构造函数进行解析 } /// <summary> /// 解析字符串构造函数 /// </summary> /// <param name="items">待解析字符串数组</param> private void ConstructEvaluator(EvaluatorItem[] items) { //创建C#编译器实例 CodeDomProvider provider = CodeDomProvider.CreateProvider("C#"); //过时了 //ICodeCompiler comp = provider.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.GenerateExecutable = false; //不生成可执行文件 cp.GenerateInMemory = true; //在内存中运行 StringBuilder code = new StringBuilder(); //创建代码串 /* * 添加常见且必须的引用字符串 */ code.Append("using System; "); code.Append("using System.Xml; "); code.Append("using System.Collections.Generic; "); code.Append("namespace Flow { "); //生成代码的命名空间为EvalGuy,和本代码一样 code.Append(" public class _Evaluator { "); //产生 _Evaluator 类,所有可执行代码均在此类中运行 foreach (EvaluatorItem item in items) //遍历每一个可执行字符串项 { code.AppendFormat(" public {0} {1}() ", //添加定义公共函数代码 item.ReturnType.Name, //函数返回值为可执行字符串项中定义的返回值类型 item.Name); //函数名称为可执行字符串项中定义的执行字符串名称 code.Append("{ "); //添加函数开始括号 code.AppendFormat("return ({0});", item.Expression);//添加函数体,返回可执行字符串项中定义的表达式的值 code.Append("}"); //添加函数结束括号 } code.Append("} }"); //添加类结束和命名空间结束括号 //得到编译器实例的返回结果 CompilerResults cr = provider.CompileAssemblyFromSource(cp, code.ToString());//comp if (cr.Errors.HasErrors) //如果有错误 { StringBuilder error = new StringBuilder(); //创建错误信息字符串 error.Append("编译有错误的表达式: "); //添加错误文本 foreach (CompilerError err in cr.Errors) //遍历每一个出现的编译错误 { error.AppendFormat("{0}", err.ErrorText); //添加进错误文本,每个错误后换行 } throw new Exception("编译错误: " + error.ToString());//抛出异常 } Assembly a = cr.CompiledAssembly; //获取编译器实例的程序集 _Compiled = a.CreateInstance("Flow._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 double EvaluateDouble(string name) { return (double)Evaluate(name); } /// <summary> /// 执行字符串并返回长整型数值 /// </summary> /// <param name="name">执行字符串名称</param> /// <returns>执行结果</returns> public long EvaluateLong(string name) { return (long)Evaluate(name); } /// <summary> /// 执行字符串并返回十进制数值 /// </summary> /// <param name="name">执行字符串名称</param> /// <returns>执行结果</returns> public decimal EvaluateDecimal(string name) { return (decimal)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> /// <returns>运算结果</returns> static public int EvaluateToInteger(string code) { DynamicEvaluator eval = new DynamicEvaluator(typeof(int), code, staticMethodName);//生成 Evaluator 类的对像 return (int)eval.Evaluate(staticMethodName); //执行并返回整型数据 } /// <summary> /// 执行表达式并返回双精度值 /// </summary> /// <param name="name">执行字符串名称</param> /// <returns>执行结果</returns> static public double EvaluateToDouble(string code) { DynamicEvaluator eval = new DynamicEvaluator(typeof(double), code, staticMethodName);//生成 Evaluator 类的对像 return (double)eval.Evaluate(staticMethodName); } /// <summary> /// 执行表达式并返回长整型数值 /// </summary> /// <param name="name">执行字符串名称</param> /// <returns>执行结果</returns> static public long EvaluateToLong(string code) { DynamicEvaluator eval = new DynamicEvaluator(typeof(long), code, staticMethodName);//生成 Evaluator 类的对像 return (long)eval.Evaluate(staticMethodName); } /// <summary> /// 执行表达式并返回十进制数值 /// </summary> /// <param name="name">执行字符串名称</param> /// <returns>执行结果</returns> static public decimal EvaluateToDecimal(string code) { DynamicEvaluator eval = new DynamicEvaluator(typeof(decimal), code, staticMethodName);//生成 Evaluator 类的对像 return (decimal)eval.Evaluate(staticMethodName); } /// <summary> /// 执行表达式并返回字符串型值 /// </summary> /// <param name="code">要执行的表达式</param> /// <returns>运算结果</returns> static public string EvaluateToString(string code) { DynamicEvaluator eval = new DynamicEvaluator(typeof(string), code, staticMethodName);//生成 Evaluator 类的对像 return (string)eval.Evaluate(staticMethodName); //执行并返回字符串型数据 } /// <summary> /// 执行表达式并返回布尔型值 /// </summary> /// <param name="code">要执行的表达式</param> /// <returns>运算结果</returns> static public bool EvaluateToBool(string code) { DynamicEvaluator eval = new DynamicEvaluator(typeof(bool), code, staticMethodName);//生成 Evaluator 类的对像 return (bool)eval.Evaluate(staticMethodName); //执行并返回布尔型数据 } /// <summary> /// 执行表达式并返回 object 型值 /// </summary> /// <param name="code">要执行的表达式</param> /// <returns>运算结果</returns> static public object EvaluateToObject(string code) { DynamicEvaluator eval = new DynamicEvaluator(typeof(object), code, staticMethodName);//生成 Evaluator 类的对像 return eval.Evaluate(staticMethodName); //执行并返回 object 型数据 } #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; } } }
资料:
类库:
https://msdn.microsoft.com/zh-cn/library/system.codedom.compiler(v=vs.110).aspx
示例文档:
https://msdn.microsoft.com/zh-cn/library/650ax5cx(v=vs.110).aspx
快速参考:
https://msdn.microsoft.com/zh-cn/library/f1dfsbhc(v=vs.110).aspx
博客
http://www.cnblogs.com/whitewolf/archive/2010/06/19/1760708.html
工具:
C#>VB:
http://www.dotnetspider.com/convert/CSharp-To-Vb.aspx