It wouldn't make any sense to add another type of extension just to cater for .NET.
.NET executables are PE files and they provide a minimal amount of native code to bootstrap the correct version of the CLR and pull the IL into memory and hand off to the CLR.
Windows natively knows what to do with PE files and with the indirection mechanism built into the EXE Windows also doesn't need to know about .NET.
With a .il file you'd need to register the extension with Windows then make sure that the correct version of the CLR is loaded - as far as I know you can only associate an extension with one executable.
To support multiple versions of the CLR you'd need some kind of intermediary that then inspects your .il file to determine which CLR to load....and things just get convoluted and fragile after that.
Packaging all this in a PE solves these problems neatly and elegantly.
Although this is an older article, the principles remains the same in current .NET Frameworks:
An In-Depth Look into the Win32 Portable Executable File Format, Part 2
The key section "The .NET Header" explains how this works:
Executables produced for the Microsoft
.NET environment are first and
foremost PE files. However, in most
cases normal code and data in a .NET
file are minimal. The primary purpose
of a .NET executable is to get the
.NET-specific information such as
metadata and intermediate language
(IL) into memory. In addition, a .NET
executable links against MSCOREE.DLL.
This DLL is the starting point for a
.NET process. When a .NET executable
loads, its entry point is usually a
tiny stub of code. That stub just
jumps to an exported function in
MSCOREE.DLL (_CorExeMain or
_CorDllMain). From there, MSCOREE takes charge, and starts using the
metadata
answered 2011-03-30T17:32:37.440