我的应用没有安装程序。它是可移植的,但我需要在它上运行ngen.exe
,因为它在启动时运行。
是否建议首次运行应用时自动运行ngen.exe
?以后会引起任何问题吗?有内置的方法吗?
答案 0 :(得分:5)
我从未阅读或听过任何此类推荐,但这是一个有趣的想法。
我说去试试它并测试它是否适用于您的情况(就您的“便携式”/“无安装人员”要求而言,这是有趣的。)
在第一次运行app时,没有内置的方式来运行NGen;但它可以在下面的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 post,NGen documentation on MSDN,an 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