zoukankan      html  css  js  c++  java
  • .NET程序在运行中创建EXE文件的技术

      我曾开发过一个.NET应用,需要在运行中动态的创建EXE文件,当时查了很多资料后才顺利实现,有一些心得,整理出来。

      要从你的.NET应用程序中动态的生成一个汇编你有两种选择:CodeDom和Reflection.Emit。在这篇文章中我将比较二者的不同,以便你作出哪种方法才是最适合你的选择。

      CodeDom和Reflection.Emit的最大不同就是CodeDom可以产生C#、VB.NET、Visual J#,以及其他.NET语言,而Reflection.Emit则是产生原始的中间语言(IL—Intermediate Language)语句。CodeDom不需要深入的IL知识,因此使用起来会容易的多。不利的方面是你被限制为一套所有语言都可以访问的动作和类型集,这消除了对超载操作或是语言专有的方言的使用。有利的方面是通过使用一个不同的代码提供者,你可以很容易的在不同的输出语言间进行切换。

      Reflection.Emit是极端强大的,它可以做许多CodeDom不能做的事情,因为它允许你编写任何合法的IL语句。Reflection.Emit的最大障碍就是它要求你理解并能够编写MSIL。Reflection.Emit为你提供了把项目连同真正的MSIL指令压入堆栈和从堆栈中弹出的能力。这在某些时候是有益的,但它也可能成为一个缺点,因为这失去了更高级语言所提供的高效的生产力。

      这个代码例子(C#写的)利用CodeDom建立了一个带有一个返回的Main,这个CodeDom产生一个高级的.NET语言:

      CodeEntryPointMethod main = new CodeEntryPointMethod();

      main.Statements.Add(new System.CodeDom.CodeMethodReturnStatement());

      这是同样的Main,但是是用Reflection.Emit来建立的,它产生原始的IL:

      MethodBuilder methodbuilder = typeBuilder.DefineMethod("Main", MethodAttributes.HideBySig | MethodAttributes.Static | MethodAttributes.Public, typeof(void), new Type[] { typeof(string[]) });

      ILGenerator ilGenerator = methodbuilder.GetILGenerator();

      ilGenerator.Emit(OpCodes.Ret);

      assemblyBuilder.SetEntryPoint(methodbuilder, PEFileKinds.ConsoleApplication);

      这里有一些明显的不同:CodeDom有一个类可以用来创建一个入口点,而Reflection.Emit代码必须手工建立方法并设置入口点。来看看返回:再一次,CodeDom有一个类可以用来做这个工作,而Reflection.Emit代码必须为返回而输出IL指令。

      你到底应该使用CodeDom还是Reflection.Emit依赖于你的情况。

      在下列情况中你应该使用CodeDom:

    • 编写一个代码生成工具。
    • 任何时候当你希望产生C#、VB.NET或任何其他高级语言时。
    • 使用C#或VB.NET代码片断时。

      在下列情况中你应该使用Reflection.Emit:

    • 需要严密的控制IL的优化。
    • 要执行不服从公共语言规范的动作,比如不安全的代码。

      假如你的汇编生成工作不属于前面所述类目中的一个,而你只需要动态的生成汇编,则你可以使用这些生成技术中的任何一种。在大多数的情况下,CodeDom将是更好的选择,因为它更容易使用,并且可以生成许多不同的语言。

      这二者都是强大的工具,用于不同的场合。你只需遵循这一基本的指导方针:如果你正在编写工具或是需要更高级的代码生成,则使用CodeDom;如果你需要对你的生成汇编进行低级控制,则使用Reflection.Emit。

  • 相关阅读:
    Mac下安装cscope和ctags
    MAC的VIMRC
    我的Linux系统的VIMRC
    关于在VI中查看BIN文件二进制值不对的问题
    没有关心过编写代码方式的好处,你是不是也是这样?
    四十不惑,真的不惑了么?
    jQuery通过text值来设置选定,以及遍历select的选项个数和遍历
    C#解析XML文件
    网页调用本地程序(Windows下浏览器全兼容)
    C#获取文件的md5
  • 原文地址:https://www.cnblogs.com/jnnybob/p/3511125.html
Copyright © 2011-2022 走看看