I have been running "ngen install ..." on an application while it is being developed. But haven't run "ngen uninstall ..." on some of the versions / scenarios (debug etc.) before those assemblies were overwritten. Now I see many *.ni.exe and *.ni.dll in folders of the form "C:\Windows\assembly\NativeImages_v4.0.30319_64\AssemblyName\hashkey". (dlls are also internally developed ones.)
I am using .Net 4.
Is there anyway to uninstall these? I have tried "ngen update" it doesn't seem to touch these orphaned native images. Of course I can delete these manually, but it will upset the ref counts on system dlls on which my assemblies depend, or have worse consequences on .net system.
Apart from taking space, these older assemblies are hurting the startup delay as assembly binder is trying to match the current IL to each of the native assemblies.
Also is there a better way to look what is in the native image cache rather than using command line?
Thanks
While this question already has an answer, there are a few things you need to consider if you want to remove stale (old) ngen'ed assemblies.
ngen display
. Using ngen display yourasm.dll
won't work (on the filename), but ngen display AssemblyName
will (internal assembly name). You can use a partial name.When you use ngen uninstall
, uninstall them in the inverse order you installed them. Dependencies won't be uninstalled, but if you manually installed a dependency before you installed the dependent assembly, you need to uninstall the dependent assembly first:
If A depends on B and C and B depends on C, and you did:
ngen install B
ngen install C
ngen install A
then you can only ever uninstall them by doing:
ngen uninstall A // removes A, if nothing is dependent on it
ngen uninstall C // removes C, it has no dependencies now
ngen uninstall B // removes B, it has no dependencies now
If you are unsure of the dependencies, check the output of ngen display asmname
, it will list the dependencies under "ROOT". Anything under there must be removed first
If found it helpful to check in the c:\windows\assembly\NativeImages_v4.0.30319_64
(and the *_32
version) with the following command whether it was still installed:
dir | findstr "AsmName"
Since there are so many files here, it helps seeing what is still there. It also helps in finding out to what version (32 bit, 64 bit, MSIL) they belong. It doesn't seem to help with what profile they were put there.
c:\windows\assembly
folder does not show assemblies that are ngen'ed, but not in the GAC. But if your assembly is also in the GAC, you can uninstall it from the GAC and from the NGen cache by right-clicking and then selecting "Uninstall".In addition to the above, having a lot of stale ngen'ed images there won't hurt performance. The CLR stores the files here based on the assembly name (name, version, public key token) and a few other heuristics (file date, internal creation date, hash). It won't even touch your old ngen'ed images. You can verify this by using Process Monitor (it only ever tries to load the ngen'ed image from one location, based on the hash etc). But I agree, it is nasty to have to keep them around.