傻强

岂是池鱼恋旧渊,敢比雄鹰上九天。
轻酌小唱性情酣,宏图霸业谈笑间。

导航

CodeDom生成代码编译后反射调用

代码:
  1using System;
  2using System.CodeDom;
  3using System.CodeDom.Compiler;
  4using System.Collections;
  5using System.IO;
  6using System.Reflection;
  7using Microsoft.CSharp;
  8
  9namespace CodeDom
 10{
 11    /// <summary>
 12    /// CodeDomMain 的摘要说明。
 13    /// </summary>

 14    public class CodeDomMain
 15    {
 16        [STAThread]
 17        public static void Main()
 18        {
 19            CodeCompileUnit codeCompileUnit = new CodeCompileUnit();
 20            CodeNamespace codeNamespace = new CodeNamespace("Sample");
 21            codeCompileUnit.Namespaces.Add(codeNamespace);
 22
 23            codeNamespace.Imports.Add(new CodeNamespaceImport("System"));
 24
 25            CodeTypeDeclaration codeTypeDeclaration = new CodeTypeDeclaration("Class1");
 26
 27            codeNamespace.Types.Add(codeTypeDeclaration);
 28
 29            //入口方法
 30            CodeEntryPointMethod codeEntryPointMethod = new CodeEntryPointMethod();
 31
 32            CodeMethodInvokeExpression codeMethodInvokeExpression = new CodeMethodInvokeExpression(
 33                new CodeTypeReferenceExpression("System.Console"),
 34                "WriteLine",
 35                new CodePrimitiveExpression("Hello CodeDom!")
 36                );
 37
 38            CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression(
 39                new CodeTypeReferenceExpression("System.Console"),
 40                "ReadLine");
 41
 42            codeEntryPointMethod.Statements.Add(codeMethodInvokeExpression);
 43            codeEntryPointMethod.Statements.Add(methodInvoke);
 44            codeTypeDeclaration.Members.Add(codeEntryPointMethod);
 45
 46
 47            //一般方法调用
 48            CodeMemberMethod mMethod = new CodeMemberMethod();
 49            mMethod.Name = "fuck";
 50            mMethod.Attributes = MemberAttributes.Public;
 51            CodeMethodInvokeExpression methodInvoke1 = new CodeMethodInvokeExpression(
 52                new CodeTypeReferenceExpression("System.Console"),
 53                "WriteLine",
 54                new CodePrimitiveExpression("fuck!")
 55                );        
 56
 57            //两个表达式间进行的二进制运算:大于
 58            CodeBinaryOperatorExpression greaterThan = new CodeBinaryOperatorExpression(
 59                new CodePrimitiveExpression(2),// 左操作数
 60                CodeBinaryOperatorType.GreaterThan,// 操作符
 61                new CodePrimitiveExpression(1// 右操作数
 62                );
 63
 64            //两个表达式间进行的二进制运算:与
 65            CodeBinaryOperatorExpression and = new CodeBinaryOperatorExpression(
 66                greaterThan,// 左操作数
 67                CodeBinaryOperatorType.BooleanAnd,// 操作符
 68                new CodePrimitiveExpression(true)// 右操作数 
 69                );
 70
 71            //if-else语句
 72            CodeConditionStatement conditionalStatement = new CodeConditionStatement(
 73                and,// 判断表达式
 74                new CodeStatement[] {},// 为真时的语句集合
 75                new CodeStatement[] {}// 为假时的语句集合
 76                );
 77            conditionalStatement.TrueStatements.Add(methodInvoke1);
 78            mMethod.Statements.Add(conditionalStatement);
 79
 80            codeTypeDeclaration.Members.Add(mMethod);
 81            
 82            //构造函数
 83            CodeConstructor cConstructor = new CodeConstructor();
 84            cConstructor.Name="Class1";
 85            cConstructor.Attributes = MemberAttributes.Public;
 86            codeTypeDeclaration.Members.Add(cConstructor);
 87
 88            //生成代码并编译
 89            ICodeGenerator cg;
 90            cg = new CSharpCodeProvider().CreateGenerator();
 91
 92            StringWriter sw = new StringWriter();
 93
 94            CodeGeneratorOptions cgOption = new CodeGeneratorOptions();
 95            cgOption.BlankLinesBetweenMembers = true;
 96            cgOption.BracingStyle = "Block";
 97
 98            cg.GenerateCodeFromCompileUnit(codeCompileUnit, sw, cgOption);
 99            Console.Write(sw.ToString());
100            Console.ReadLine();
101
102            ICodeCompiler cc = new CSharpCodeProvider().CreateCompiler();
103            CompilerParameters cp = new CompilerParameters(); //声明一个编译选项类
104            cp.GenerateExecutable = true//生成exe文件
105            cp.OutputAssembly = "HelloCodeDom.exe"//输出文件
106            cp.GenerateInMemory = true//在内存中生成
107
108            CompilerResults cr = cc.CompileAssemblyFromDom(cp, codeCompileUnit); //编译
109
110            //生成程序集
111            Assembly ass = cr.CompiledAssembly;
112
113            //反射调用
114            Type type = ass.GetType("Sample.Class1");
115            ConstructorInfo conInfo = type.GetConstructor(new Type[]{});
116            object fooOne = conInfo.Invoke(new object[]{});
117
118            Console.Write("反射调用主函数:");
119            type.GetMethod("Main").Invoke(fooOne,new object[]{});
120            Console.Write("反射调用普通函数:");
121            type.GetMethod("fuck").Invoke(fooOne,new object[]{});
122
123            displayCompilerResults(cr);
124            Console.ReadLine();
125        }

126
127        /// <summary>
128        /// 显示编译结果
129        /// </summary>
130        /// <param name="cr"></param>

131        public static void displayCompilerResults(CompilerResults cr)
132        {
133
134            Console.WriteLine("\n编译结果:");
135            // If errors occurred during compilation, output the compiler output and errors.
136            if (cr.Errors.Count > 0)
137            {
138                for (int i = 0; i < cr.Output.Count; i++)
139                    Console.WriteLine(cr.Output[i]);
140                for (int i = 0; i < cr.Errors.Count; i++)
141                    Console.WriteLine(i.ToString() + "" + cr.Errors[i].ToString());
142
143            }

144            else
145            {
146                // Display information about the compiler's exit code and the generated assembly.
147                Console.WriteLine("Compiler returned with result code: " + cr.NativeCompilerReturnValue.ToString());
148                Console.WriteLine("Generated assembly name: " + cr.CompiledAssembly.FullName);
149                if (cr.PathToAssembly == null)
150                    Console.WriteLine("The assembly has been generated in memory.");
151                else
152                    Console.WriteLine("Path to assembly: " + cr.PathToAssembly);
153
154                // Display temporary files information.
155                if (!cr.TempFiles.KeepFiles)
156                    Console.WriteLine("Temporary build files were deleted.");
157                else
158                {
159                    Console.WriteLine("Temporary build files were not deleted.");
160                    // Display a list of the temporary build files
161                    IEnumerator enu = cr.TempFiles.GetEnumerator();
162                    for (int i = 0; enu.MoveNext(); i++)
163                        Console.WriteLine("TempFile " + i.ToString() + "" + (string) enu.Current);
164                }

165            }

166        }

167
168
169    }

170}

生成的代码:
 1//------------------------------------------------------------------------------
 2// <autogenerated>
 3//     This code was generated by a tool.
 4//     Runtime Version: 1.1.4322.985
 5//
 6//     Changes to this file may cause incorrect behavior and will be lost if
 7//     the code is regenerated.
 8// </autogenerated>
 9//------------------------------------------------------------------------------
10
11namespace Sample {
12    using System;
13
14
15    public class Class1 {
16
17        public Class1() {
18        }

19
20        public static void Main() {
21            System.Console.WriteLine("Hello CodeDom!");
22            System.Console.ReadLine();
23        }

24
25        public virtual void fuck() {
26            if (((2 > 1)
27                        && true)) {
28                System.Console.WriteLine("fuck!");
29            }

30        }

31    }

32}

33


生成的代码编译后的输出:
反射调用主函数:Hello CodeDom!

反射调用普通函数:fuck!

编译结果:
Compiler returned with result code: 0
Generated assembly name: HelloCodeDom, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
The assembly has been generated in memory.
Temporary build files were deleted.

posted on 2005-05-13 14:15  傻强  阅读(773)  评论(1)    收藏  举报