首次运行时自动运行Ngen.exe

时间:2013-08-07 11:27:52

标签: c# .net vb.net build ngen

我的应用没有安装程序。它是可移植的,但我需要在它上运行ngen.exe,因为它在启动时运行。

是否建议首次运行应用时自动运行ngen.exe?以后会引起任何问题吗?有内置的方法吗?

2 个答案:

答案 0 :(得分:5)

是否建议首次运行应用程序时自动运行ngen.exe?

我从未阅读或听过任何此类推荐,但这是一个有趣的想法。

我说去试试它并测试它是否适用于您的情况(就您的“便携式”/“无安装人员”要求而言,这是有趣的。)

是否有内置方法可以做到?

在第一次运行app时,没有内置的方式来运行NGen;但它可以在下面的PoC演示中完成。

PoC代码

以下PoC代码包含code from a related SO answer

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;

namespace SelfNgenPoC
{
    class Program
    {
        static void Main(string[] args)
        {
            /*
             * Check whether the app has been NGen'd with code adapted from
             * https://stackoverflow.com/a/20593260/1810429, which also outlines
             * an alternative approach - by running...
             *     ngen.exe display <assemblyPath>
             * ...and checking the result - 0 if the app is already NGen'd and
             * -1 if it is not.
             */

            Process process = Process.GetCurrentProcess();

            ProcessModule[] modules = new ProcessModule[process.Modules.Count];
            process.Modules.CopyTo(modules, 0);

            var niQuery =
                from m in modules
                where m.FileName.Contains(@"\" + process.ProcessName + ".ni")
                select m.FileName;
            bool ni = niQuery.Count() > 0 ? true : false;

            // FORNOW: for PoC debugging and sanity checking
            if (ni)
                Console.WriteLine("Native Image: " + niQuery.ElementAt(0));
            else
                Console.WriteLine("IL Image: " + process.MainModule.FileName);

            /*
             * NGen the app if not.
             */

            if (!ni)
            {
                // FORNOW: for PoC debugging and sanity checking
                Console.WriteLine("The app is not NGen'd.");
                Console.WriteLine("NGen'ing the app...");

                var assemblyPath = process.MainModule.FileName;

                ProcessStartInfo startInfo = new ProcessStartInfo();
                // TODO: Determine the path to (the appropriate version of)
                // ngen.exe.
                // FORNOW: Just use a hardcoded path to ngen.exe for PoC.
                startInfo.FileName =
                    @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe";
                startInfo.Arguments = "install \"" + assemblyPath + "\"";
                // TBD: process options that you think make sense
                startInfo.CreateNoWindow = false;
                startInfo.UseShellExecute = false;
                startInfo.WindowStyle = ProcessWindowStyle.Hidden;

                try
                {
                    using (Process exeProcess = Process.Start(startInfo))
                    {
                        exeProcess.WaitForExit();
                    }
                }
                catch
                {
                    // TBD: error handling that you think makes sense - e.g.
                    // logging or displaying the error, moving on regardless
                    // etcetera.
                }
            }
            else
            {
                // FORNOW: for PoC debugging and sanity checking
                Console.WriteLine("The app is already NGen'd.");
            }

            /*
             * Carry on with whatever your app does.
             */
        }
    }
}

首次运行

C:\bin\SelfNgenPoC>.\SelfNgenPoC.exe
IL Image: C:\bin\SelfNgenPoC.exe
The app is not NGen'd.
NGen'ing the app...
Microsoft (R) CLR Native Image Generator - Version 4.0.30319.18408
Copyright (c) Microsoft Corporation.  All rights reserved.
1>    Compiling assembly C:\bin\SelfNgenPoC.exe (CLR v4.0.30319) ...

C:\bin\SelfNgenPoC>

后续运行

C:\bin\SelfNgenPoC>.\SelfNgenPoC.exe
Native Image: C:\Windows\assembly\NativeImages_v4.0.30319_32\SelfNgenPoC\a461633
0444188e116025424c70d15f1\SelfNgenPoC.ni.exe
The app is already NGen'd.

C:\SelfNgenPoC>

以后会引起任何问题吗?

NGen组装是否有意义取决于许多因素,您可以在an MSDN blog postNGen documentation on MSDNan older but relevant "MSDN Magazine" article和其他地方查看这些因素。

最终只有你对你的应用程序了解得足以确定它对NGen(任何,部分或全部)程序集是否有意义。

假设确实在您的情况下有意义,我不认为它会根据您所描述的内容导致任何明显的问题。

请务必牢记NGen的标准责任 - 尤其是NGen MSDN文档中提到的这一点......

  

当原始程序集或其中一个依赖项得到服务时,需要重新生成映像。

......应该可以通过一点点自我NGen的逻辑来管理。

答案 1 :(得分:1)

如果你正在使用dotNEt&gt; 4.5

public App(){
    ProfileOptimization.SetProfileRoot(@"C:\MyApp");
    ProfileOptimization.StartProfile("Start.Profile");
}

将它放在程序的最开头。首次启动应用程序/配置文件时,会创建配置文件。 MSDN