前面说了这么多,大家可能会觉得,好像没弄出个玩意儿来啊,对啊,所以,本文就来个可以弄出个玩意儿的东东。
说明一下,这是一个综合示例,分为两大部分,第一部分,生成代码,输出到控制台窗口中;第二部分,把这些代码动态进行编译,并生成一个WinForm应用程序,双击动态编译的程序可以运行起来,点击窗口上的按钮,会弹出一个对话框。
好,下面我把整个示例的代码贴出来,很简单,你就新建一个控制台应用程序就可以了。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;
namespace Example
{
class Program
{
static void Main(string[] args)
{
CodeCompileUnit MyUnit = new CodeCompileUnit();
// 一个命名空间
CodeNamespace MyNamespace = new CodeNamespace("MyApp");
MyNamespace.Imports.Add(new CodeNamespaceImport("System"));
MyNamespace.Imports.Add(new CodeNamespaceImport("System.Windows.Forms"));
MyNamespace.Imports.Add(new CodeNamespaceImport("System.Drawing"));
MyNamespace.Imports.Add(new CodeNamespaceImport("System.Text"));
// 定义一个类
CodeTypeDeclaration MyClass = new CodeTypeDeclaration("MainForm");
MyClass.Attributes = MemberAttributes.Public;
MyClass.BaseTypes.Add(new CodeTypeReference("Form"));
CodeMemberField buttonField = new CodeMemberField("Button", "button1");
buttonField.InitExpression = new CodePrimitiveExpression(null);
MyClass.Members.Add(buttonField);
// 构造函数
CodeConstructor MyConstr = new CodeConstructor();
// 实例化Button类
MyConstr.Statements.Add(
new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "button1"),
new CodeObjectCreateExpression("Button", new CodeExpression[] { })));
// 为Button实例的相关属性赋值
MyConstr.Statements.Add(new CodeAssignStatement(
new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "button1"), "Text"),
new CodePrimitiveExpression("请点击这里")
));
MyConstr.Statements.Add(new CodeAssignStatement(
new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "button1"), "Width"),
new CodePrimitiveExpression((int)285)
));
MyConstr.Statements.Add(new CodeAssignStatement(
new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "button1"), "Height"),
new CodePrimitiveExpression((int)65)
));
MyConstr.Statements.Add(new CodeAssignStatement(
new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "button1"), "Location"),
new CodeObjectCreateExpression("Point", new CodePrimitiveExpression((int)60), new CodePrimitiveExpression((int)80))
));
// 绑定Button的Click事件
MyConstr.Statements.Add(new CodeAttachEventStatement(
new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "button1"), "Click",
new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), "button1_Click")
));
// 设置窗口的宽度和高度
MyConstr.Statements.Add(new CodeAssignStatement(
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(),"Width"),
new CodePrimitiveExpression((int)450)
));
MyConstr.Statements.Add(new CodeAssignStatement(
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Height"),
new CodePrimitiveExpression((int)300)
));
// 设置窗口标题
MyConstr.Statements.Add(new CodeAssignStatement(
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Text"),
new CodePrimitiveExpression("我的应用程序")
));
// 将Button变量添加到Form的控件集合中
MyConstr.Statements.Add(new CodeExpressionStatement(
new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(),"Controls"),
"Add",
new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "button1"))
));
MyClass.Members.Add(MyConstr);
// 按钮单击处理程序
CodeMemberMethod MyHandlerMethod = new CodeMemberMethod();
MyHandlerMethod.Attributes = MemberAttributes.Private;
MyHandlerMethod.Name = "button1_Click";
MyHandlerMethod.Parameters.Add(new CodeParameterDeclarationExpression("Object", "sender"));
MyHandlerMethod.Parameters.Add(new CodeParameterDeclarationExpression("EventArgs", "e"));
// 方法中的描述
MyHandlerMethod.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(
new CodeTypeReferenceExpression("MessageBox"),
"Show",
new CodePrimitiveExpression("你好啊,欢迎点击。"))
));
// 将方法添加到类成员中
MyClass.Members.Add(MyHandlerMethod);
// 将类添加到命名空间
MyNamespace.Types.Add(MyClass);
// 将命名空间添加到编译单元
MyUnit.Namespaces.Add(MyNamespace);
// 入口点函数
CodeEntryPointMethod main = new CodeEntryPointMethod();
main.Statements.Add(new CodeExpressionStatement(
new CodeMethodInvokeExpression(
new CodeTypeReferenceExpression("Application"),
"Run",
new CodeObjectCreateExpression("MainForm", new CodeExpression[] { })
)
));
MyClass.Members.Add(main);
// 输出生成的代码
CodeDomProvider provider = CodeDomProvider.CreateProvider("cs");
provider.GenerateCodeFromCompileUnit(MyUnit, Console.Out, new CodeGeneratorOptions { BracingStyle = "C" });
// 编译程序集
CompilerParameters param = new CompilerParameters();
param.CompilerOptions = @"/t:winexe /out:Myapp.exe ";
param.IncludeDebugInformation = false;
param.ReferencedAssemblies.Add("mscorlib.dll");
param.ReferencedAssemblies.Add("System.Drawing.dll");
param.ReferencedAssemblies.Add("System.Windows.Forms.dll");
param.ReferencedAssemblies.Add("System.dll");
CompilerResults result = provider.CompileAssemblyFromDom(param, MyUnit);
if (result.Errors.Count!=0)
{
Console.WriteLine("\n------------------- 编译错误 -------------------------- ");
foreach (CompilerError err in result.Errors)
{
Console.WriteLine("信息:{0}",err.ErrorText);
}
}
else
{
Console.WriteLine("编译成功。");
}
Console.ReadKey();
}
}
}
运行程序,代码生成完成,并且成功编译,如下图所示。
那么,生成的WinForm程序在哪儿呢?上面代码中使用了 /out:Myapp.exe 参数,那么这个EXE在哪呢,相对路径,也就是和当前应用程序在同一个目录,现在,打开你的项目所在的位置,找到 \bin\Debug,看到那个Myapp.exe没?看到了就双击运行。好的,奇迹的一刻发生了。
怎么样?这回该有点玩意儿了吧?
总结一下,这个动态生成代码,说实话,平时用到它的机会不多,所以,我也没详细讲述,再者,用起来也不复杂,痛苦的是思路。所以,有人问,这个动态生成或动态编译在实际应用中有啥用处?呵呵,开玩笑地回答你:做木马!呵呵。
分享到:
相关推荐
很牛的带Ajax功能的ASP.NET+C#代码生成工具,能生成从表示层到SQL脚本的所有代码,只需使用VS2008+SQL2005(无需编码,生成后将代码加入我提供的框架就成一个项目,编译后即可使用)生成前需将数据库按要求设计好,...
.NET Reflector 工具及插件:Reflexil,用于C#反编译出软件源码并可以修改。
.net 代码反编译工具,可以用来查看未被加密的.net程序的源代码.
.Net Core - 源代码动态编译
两大最受欢迎的C#工具 一个是反编译的工具.NET Reflector 8.0.2.313 官方最新破解版 一个是dll混淆工具Xenocode Postbuild 2010 for .NET 另附破解教程以及使用教程 亲测绝对可用
.net 反编译.net 反编译.net 反编译.net 反编译.net 反编译.net 反编译.net 反编译.net 反编译.net 反编译
深入剖析ASP.NET的编译原理之一:动态编译(Dynamical Compilation)
多个.Net代码生成器合集,部分包括源码,适应各种.Net开发模式,模板型,自定义型,适合不用应用。 AutoCodeForMVC代码生成器源码, CodeFluentEntitiesModelerSetup_gpxz, HaoCodeBuilder1.1, Jirisoft.Code...
与代码混淆工具(Obfuscator)相比,.NET Reactor 可以完全阻止对 .NET 程序集(由 C#, VB.NET, Delphi.NET, J#, MSIL… 等语言编写)的反编译。通俗的讲,.NET Reactor 在破解者和您的 .NET 代码之间构建了强大的防...
如何用C#动态编译、执行代码 在开始之前,先熟悉几个类及部分属性、方法:CSharpCodeProvider、ICodeCompiler、...大致了解以上知识之后,就可以使用C#动态的编译并执行代码了,以下是一段示例程序:
深入剖析ASP.NET的编译原理.rar
①彻底征服.Net运行和编译原理:.Net Framework深入手动编译、CLR、CLS、CTS、JIT等。
可以反编译.NET代码的一个工具,支持四种语言:IL,VB.net,C#,Delphi,是程序员必备的工具。
.net 文档生成工具用于将xml 文档注释生成格式类似MSDN的HTML帮助文档,并编译为CHM文档。 .NET文档生成工具的特点有: 1、合并多个程序集; 2、自动搜索程序集及其引用的程序集对应的XML文档(包括.Net自带的程序...
在编写数据库连接代码时,可以利用工具直接编译产生连接代码,很方便,很强大。支持SQL,Oracle,Access三种数据库的连接。
.Net Core - 源代码动态编译V2
Reflector for .NET Remotesoft .NET Explorer .dll 文件反编译的工具软件: Reflector for .NET Remotesoft .NET Explorer Remotesoft .NET Explorer 支持asp.net2.0 要真正反编译.dll文件就在网站上使用该软件去...
内含ppt,视频,文档,示例,非常好!!!!!!!!!!!!!!!!!
vb.net执行代码段 自解释自编译
.NET Reactor 用于.NET程序的加密、混淆、加壳,防止程序被反编译