A first hand look from the .NET engineering teams
After installing .NET 4.0 or later you may notice something a little unusual about your .NET processes. Here is a partial list of the loaded modules of a simple “Hello World” executable compiled with the .NET 2.0 compiler.
start end module name
60f00000 61491000 mscorwks C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
6c650000 6c6b6000 mscoreei C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscoreei.dll
6d420000 6d46a000 MSCOREE C:\Windows\SYSTEM32\MSCOREE.DLL
75a80000 75aca000 KERNELBASE C:\Windows\system32\KERNELBASE.dll
Something here looks out of place – the mscoreei.dll file is loaded from the v4.0.30319 folder. What is it doing there next to the main clr dll (mscorwks.dll) from v2.0.50727? Actually, that’s the expected behavior. We call mscoreei.dll the “shim implementation”, or “shim impl” for short, and it’s new for .NET 4.0. The third dll in the list above, previously known as the “shim”, is now more accurately known as the “shell shim”. The two are tightly paired to do the main job that was previously done by mscoree alone – providing the interfaces for loading the runtime. Generally speaking, the shell shim now consists of thin wrapper functions, each of which delegates its functionality to a corresponding function in the shim implementation.
Why the split? We’ve seen significant numbers of machine reboots as part of .NET redist installation, typically due to needing to update a file that is in use. The most common file in use has been mscoree.dll, which is loaded by every single .NET application, and even some services such as MSI. As a result, we undertook the mscoree “split” to avoid machine reboots. By moving the shim implementation into a version-specific file, we are able to deploy a new version of mscoreei.dll (say in the v5.0 .NET folder, as part of .NET 5.0 installation), without touching the machine-wide mscoree.dll file. The next time a managed app is run, mscoree will dynamically find the new mscoreei and defer each of its function calls to it. That way we can deploy new versions of the framework on a machine running existing managed applications without requiring a restart.
Note that mscoree always uses the newest mscoreei it can find, but the actual runtime that is loaded is a completely different question. Therefore it shouldn’t be a surprise to see a newer version of mscoreei loaded with older versions of runtime dlls in the same process. In fact, CLR versions have been running with the latest shim for many years now. If I examine file versions when running a .NET 1.1 app on a machine that has both .NET 1.1 and .NET 2.0 installed I can see that I am using a shim newer than the runtime.
79000000 79045000 mscoree C:\WINDOWS\system32\mscoree.dll
File version: 2.0.50727.42
791b0000 79412000 mscorwks C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\mscorwks.dll
File version: 1.1.4322.573
The difference now is that the split of the shim makes it more obvious that the shim version doesn’t always match the runtime version because the version number is right there in the path of the shim impl.
This brings to mind an aphorism from David Wheeler: All problems in computer science can be solved by another level of indirection.
Hi CLR Team. Can you write article about new assembly load mechanism in .net 4.0? As I read and as I can see on 32 bit windows xp .net does not use LoadLibrary to load assemblies so there is no modules for loaded assemblies in process module list. But on 64 bit WIndow 7 I still see them. Also i noticed "strange" behavior of Marshal.GetHINSTANCE(Module). It still returns some value and it is not hInstance of Entry Assembly, so this behavior breaks some my PInvoke calls to winapi.
Can someone tell me how to get this file off of my computer. It was placed on there by someone with Norton and does not work and I can't get it to uninstall.
2 days ago and said to a customer that installing .net 4.0 on a system will not affect the existing software as no one will load the new libraries. And I was sure of this!
Right now i'm trying to get a hold of a deadlock in a 2.0 app (GC lock while loading an assembly), which only seems to happen when .net 4.0 is installed on the system. Actually is more like "it increases the chances'.
Till now I did not understand how .net 4.0 could affect the 2.0 runtime, until I saw in windbg that loaded mscoreei.dll library from the 4.0 framework.
And it's 12am....
@Abhishek, you mentioned v5.0. You guys work so swiftly. Can I expect it by 2014.
Again, not to forget, Gr8 post.
.NET is awesome as well as the team. Hats off to everyone.
I have a legacy code that uses c,c++,com & c#2. After installing framework 4 the application crash upon loading. renaming the C:\Windows\Microsoft.NET\Framework\v4.0.30319 to soemthing else (hence loads mscoreei of v2) solves the issue. Is it because of this mechanism described here? if yes, how can I control the flow so it will load only the .net2 dlls?
Hi CLR team can u plz tell me the first version of clr posted by clrteam
@Harika -- The first version of CLR was 1.0.3705.