If you are using Whidbey, you may notice a dll named mscorlib.ni.dll is loaded in every managed application.
It is the native image of mscorlib.dll.
Makes perfect sense, right?
Except in v1.0/v1.1, mscorlib's native image is still mscorlib.dll.
So why are we making this change?
You guess......Surprise! It is because of .local.
Remember the .local magic where you can have a <your-app-name>.exe.local file/directory, and OS will load your local copy of dlls, instead of the ones in system directory?
Say you have foo.dll. You ngen it. You have .local enabled, and you have foo.dll in your local directory. When you try to load foo.dll, CLR finds out that foo.dll has a native image, and tries to use the native image. So CLR calls LoadLibrary to load foo's native image. OS finds out .local is enabled, and there is a copy of foo.dll in local directory. It then returns the foo.dll in local directory. Since the one in local directory actually contains IL image, while CLR expects a native image, CLR panics.
We workaround this problem by inserting ".ni" in the native image's file name.