深入本机影像生成器(Ngen.exe)工具使用方法详解

先介绍一点背景知识;.Net程序在运行时会实时(JIT)编译,将.Net程序文件编译成cpu认识的汇编机器码。实时编译需要消耗额外的cpu和内存资源,这对于服务器端程序是无关紧要的,因为实时编译只在程序第一次运行时编译,之后就不需要再做了;如果你在做的是一个较大的winform程序或者silverlight等客户端程序时就需要考虑提前编译了。
.Net framework安装目录下(类似C:\Windows\Microsoft.NET\Framework\v4.0.30319)有一个ngen.exe工具,就是做这件事儿的。这个程序是一个控制台程序,最常用的使用方法如下:
生成文件filepath的native code使用下面命令:

  复制代码 代码如下:

  ngen install filepath

卸载文件filepath的native code使用下面命令

  复制代码 代码如下:

  Ngen uninstall filepath

本文主要就用这两种用法,有关这个工具更多的参数和介绍,请参考msdn
客户端程序我们必然要制作安装包,我的思路是在安装程序时就做本机映象的生成操作;我们可以在安装程序中添加一步自定义操作来做这件事情。
如果你对本文的话题感兴趣,不妨按照下面步骤试一下。
1. 新建解决方案,名字随意
2. 在新解决方案中添加一个winform项目,假定我们要对这个winform项目生成的可执行文件做本机映象生成操作;这只是一个演示,所以这个项目什么都不做
3. 在这个解决方案中添加一个名字为NgenInstaller的类库项目,并新建一个Installer Class;

  

在新建的NgenInstaller类中添加在安装时使用ngen安装程序的功能代码。
4. 代码实现很简单就是使用Process执行ngen程序来完成安装。需要注意的时,具体让ngen安装那些文件时通过Context.Parameters[“ngen1|2|3”]传进来的,这个参数需要在制作安装包的自定义步骤中设置。
实现代码:

  复制代码 代码如下:

  using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Configuration.Install; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.IO; 
using System.Diagnostics;

namespace NgenInstaller 

    [RunInstaller(true)] 
    public partial class NgenInstaller : System.Configuration.Install.Installer 
    { 
        public NgenInstaller() 
        { 
            InitializeComponent(); 
        }

public override void Install(IDictionary stateSaver) 
        { 
            NgenFile(InstallTypes.Install); 
        }

public override void Uninstall(IDictionary savedState) 
        { 
            NgenFile(InstallTypes.Uninstall); 
        }

private enum InstallTypes 
        { 
            Install, 
            Uninstall 
        }

private void NgenFile(InstallTypes options) 
        { 
            string envDir = RuntimeEnvironment.GetRuntimeDirectory(); 
            string ngenPath = Path.Combine(envDir, "ngen.exe"); 
            string exePath = Context.Parameters["assemblypath"];             
            string appDir = Path.GetDirectoryName(exePath);

int i = 1;

do { 
                string fileKey = "ngen" + i; 
                //需要生成本机映象的程序集名字,配置在ngen1...5,6的配置中 
                if (Context.Parameters.ContainsKey(fileKey)) 
                { 
                    string ngenFileName = Context.Parameters["ngen" + i]; 
                    string fileFullName = Path.Combine(appDir, ngenFileName); 
                    string argument = (options == InstallTypes.Install ? "install" : "uninstall") + " \"" + fileFullName + "\"";

Process ngenProcess = new Process(); 
                    ngenProcess.StartInfo.FileName = ngenPath; 
                    ngenProcess.StartInfo.Arguments = argument; 
                    ngenProcess.StartInfo.CreateNoWindow = true; 
                    ngenProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
                    ngenProcess.Start();

ngenProcess.WaitForExit(); 
                    i++; 
                } 
                else { 
                    break; 
                } 
            } 
            while (true); 
        } 
    } 
}

这个类库中只有这一个类,完成我们要的操作
5. 最后一步是制作安装程序,在解决方案中添加安装项目

  

  添加安装程序之后右击安装项目添加项目输出,如下图所示

  

  在添加项目输出的对话框中选择Winforms项目和刚建的类库。
然后右击安装项目选择视图---自定操作打开自定义操作窗口,添加一个名字为“Ngen生成本机映象”的自定义操作,在添加操作时要选择NgenInstaller项目输出 如下图:

  

  然后将自定义操作的名字修改为“Ngen生成本机代码”,如下图所示

  

  然后右击新建的自定义操作,选择属性窗口,在属性窗口的CustomActionData属性中添加需要操作的程序集,注意CustomActionData是一个键值对,每个键值对以/开始

  

  完成这一步就差不多了,你可以编译一下整个解决方案。运行安装项目生成的安装包。
6. 运行安装包,如果一切正常的话就做了本机映象生成了,可以通过ngen display filePath命令来验证native本机影响是否安装正常,如下命令行输出

  

附件中是测试项目源码。希望这篇文章有用。

标签: 工具 Ngen.exe

c#程序打包、机器代码生成(Ngen.exe)的更多相关文章

  1. Windows服务项目打包成安装包(Windows服务)-----------VS2017项目程序打包成.msi或者.exe

    VS2017项目程序打包成.msi或者.exe Windows服务项目使用VS2017项目程序打包成.msi或者.exe安装包 项目打包成安装包(Windows服务) 1.安装打包插件:Microso ...

  2. VS2017项目程序打包成.msi或者.exe

    VS2017项目程序打包成.msi或者.exe 1.安装打包插件:Microsoft Visual Studio 2017 Installer Projects 打开vs2017 ,选择 工具 --& ...

  3. 如何将Python的py程序打包成跨平台的exe文件

    在编写了自己的第一个可以爬写网页源代码的程序之后,发现如果在没有安装了pythonLDLE程序的计算机上根本就跑不出来.所以开始寻找可以将程序打包成跨平台运行的exe文件. 经过自己费力的谷歌没有一个 ...

  4. 将Java程序打包成可执行EXE文件的步骤

    需要的工具myeclipse .jar2exe(附上下载地址,直接解压就可以用链接: https://pan.baidu.com/s/1qYPRgXu 密码: wbva) 1.将Java项目导出成.j ...

  5. VS2017桌面应用程序打包成.msi或者.exe

    百度很难搜索到相关内容,分享下,需要的盆友拿去,不谢. http://xm2013.com/#/d/12 youtube地址:https://www.youtube.com/watch?v=z0v6h ...

  6. Qt程序打包成exe可执行文件图文教程(图文并茂,且用到了filepack)

    很多Qt爱好者想发布自己的Qt软件,但却发现在其他没有安装Qt SDK的机器上无法运行,这就是本文想要说明的问题.现在网上大部分软件都要发布自己开发的应用程序,都会打包到exe文件中,待安装完exe文 ...

  7. 将Python 程序打包成 .exe格式入门

    PyInstaller PyInstaller 是一个十分有用的第三方库,可以用来打包 python 应用程序,打包完的程序就可以在没有安装 Python 解释器的机器上运行了. 它能够在 Windo ...

  8. Java桌面程序打包成exe可执行文件

    前言: 我们都知道Java可以将二进制程序打包成可执行jar文件,双击这个jar和双击exe效果是一样一样的,但感觉还是不同.其实将java程序打包成exe也需要这个可执行jar文件. 准备: ecl ...

  9. JAVA程序打包成exe文件详细图解

    我们都知道Java可以将二进制程序打包成可执行jar文件,双击这个jar和双击exe效果是一样一样的,但感觉还是不同.其实将java程序打包成exe也需要这个可执行jar文件. 准备: eclipse ...

随机推荐

  1. dd---复制文件并对原文件的内容进行转换和格式化处理

    dd命令用于复制文件并对原文件的内容进行转换和格式化处理.dd命令功能很强大的,对于一些比较底层的问题,使用dd命令往往可以得到出人意料的效果.用的比较多的还是用dd来备份裸设备.但是不推荐,如果需要 ...

  2. iotop---监控磁盘I/O 使用状况

    iotop命令是一个用来监视磁盘I/O使用状况的top类工具.iotop具有与top相似的UI,其中包括PID.用户.I/O.进程等相关信息.Linux下的IO统计工具如iostat,nmon等大多数 ...

  3. Spring-statemachine fork一个region后不能进入join状态的问题

    Spring-statemachine版本:当前最新的1.2.3.RELEASE版本 发现fork多个Region时,子状态全部完成后能够进入join状态.但是如果fork一个Region时Regio ...

  4. ti-sdk-evm-am335x-05.07 uboot分析(MLO跳转到u-boot之前)

    --------------------------------------------------------------------------------                     ...

  5. 參加北京bluemix云计算大会偶记

    我就不写散文了.博客也要轻量化. 记录心路历程吧. 这是一次ibm的技术大会.也是传道大会,洗脑大会.会议主题看起来非常多,占领了北京国际饭店的三层,作为一个老ibm bp感受非常多. 1.北京的创业 ...

  6. 设计模式之九:建造者模式(Builder)

    建造者模式: 将一个复杂对象的建造过程和它的表示分离开来,这样同样的建造过程能够创建不同的表示. Separate the construction of a complex object from ...

  7. Ubuntu14环境下minigui安装问题记录--object.lo错误

    minigui3.0.12在Ubuntu14上面编译只是去?出现这个错误:object.h:275:9: error: incompatible types when assigning to typ ...

  8. pip报错

    You are using pip version 9.0.1, however version 10.0.1 is available.You should consider upgrading v ...

  9. BZOJ 1503 treap

    思路: treap (算是基本操作吧-..) 加减的操作数很少 就暴力好啦 每回判断一下最小的数是不是比M小 如果是 就删,继续判断 搞定. //By SiriusRen #include <c ...

  10. oracle 高水位线问题

    --查询高水位线 50295 0 28185 0select blocks, empty_blocks from dba_tables where table_name='TODAYOTHERCONS ...