CodeDom生成代码编译后反射调用
代码:
生成的代码:
1
using System;
2
using System.CodeDom;
3
using System.CodeDom.Compiler;
4
using System.Collections;
5
using System.IO;
6
using System.Reflection;
7
using Microsoft.CSharp;
8
9
namespace 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
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
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
11
namespace 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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.
浙公网安备 33010602011771号