The file format for CLI components is a strict extension of the current Portable Executable (PE) file format. This extended PE32 format enables the operating system to recognize runtime images, accommodates code emitted as CIL or native code, and accommodates runtime metadata as an integral part of the emitted code.
The following picture shows the parts of the standard .NET PE32 file. This is an .exe PE file. A managed .dll file looks almost the same. Notice that all but the PE/COFF header is in the .text section.
For Windows XP and later, the operating system loader has knowledge of managed executables, and as such calls _CorExeMain directly. For previous versions of Windows, the following happens when the exe is started:
- Loading of dll files. Import address table indicates that we should load mscoree.dll.
- The address of the invocation stub is retrieved from the PE header.
- The invocation stub is called. It again calls _CorExeMain from mscoree.dll.
- _CorExeMain checks minimum runtime version and loads runtime.
- _CorExeMain calls the EntryPointToken, and execution of .NET module is starting.
It is worth noting that the CLR Startup Shim is not installed side-by-side. Installing a new version of the .NET Framework overwrites the current version of the CLR Startup Shim. Because of this the requirement for backwards compatibility is extremely high. The shim exists in the file mscoree.dll and is in the Windows system directory.