This question might look a bit foolish or odd but I have heard a lot of about .NET CLR, JIT compiler and how it works blah blah blah... But now I am wondering where exactly it i
where exactly it is located or hosted
It is just a plain DLL, you'll find back the x86 version of it in C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll. The x64 version is in the Framework64 directory. The .NET v2 version had a different name, mscorjit.dll, find it back in the v2.0.50727 directories.
It is not "hosted" at all, the operating system is completely unaware that it exists. The CLR knows how to locate and load it. Necessarily so, it is the CLR that decides when to start a program. It simply has the DLL name hard-coded and use LoadLibrary("clrjit.dll") to load it, GetProcAddress("getJit") to get the factory function. Something you can see back in the CoreCLR source code, albeit that the jitter is not a separate DLL anymore in that CLR version.
You can see the CLR with Explorer as well, again just a plain DLL. It is clr.dll in the v4 versions, mscorwks.dll and mscorsvc.dll in the v2 versions. Two different ones back then with different garbage collectors, "wks" is the workstation version, "svc" is the server version. Compare to the <gcServer>
config file entry.
Which moves the question to "how does the CLR get loaded?" That's the job of c:\windows\syswow64\mscoree.dll, you'll use c:\windows\system32\mscoree.dll when you target x64 in your EXE project. Every .NET assembly has 5 or 9 bytes of unmanaged code, a jump into that DLL. Either _CorExeMain or _CorDllMain, depending on whether the assembly was built as an exe or a library. mscoree.dll takes a look at the metadata in the assembly and decides what version of the CLR needs to loaded so it can be properly executed.
Lots more shenanigans going on, I just posted the 10,000 feet view you asked for. If this interests you then you probably want to find out more about custom CLR hosting to see the man behind the curtain.
This is based upon my understanding and will guide you towards you answer, but may not be fully flushed out.
The EXE/DLL files that make up the DotNet Runtime (CLR, etc.) are located in the following locations:
C:\Windows\Microsoft.NET\Framework // for the 32 bit runtime
C:\Windows\Microsoft.NET\Framework64 // for the 64 bit runtime
Within there, you have the different editions such as 2.0.50727, 3.0, 3.5, and 4.0.30319 (versions on my system today).
This is where MSBuild, as well as the files that are registered with IIS are located and run from.
I don't know if this ends up being hosted by Windows at runtime, or if there is an actual EXE you could attach to with a debugger and see in the task manager.
Hopefully this provides some more insight for you.
How Windows Operating System triggers/executes .NET Executable Runs inside .NET Runtime?
Every .NET managed assembly or executable has special CLR headers, which you can see by viewing the assembly in ILDASM. This headers points to the version of the runtime that needs to be loaded. Also, there is the Image Section with the Import Address Table
, pointing to what needs to be loaded:
----- Image sections:
Import Address Table
DLL : mscoree.dll
0x00002000 Import Address Table
0x0000a37e Import Name Table
0 Time Date Stamp
0 Index of First Forwarder Reference
0x0000 _CorDllMain
----- CLR Header:
Header size: 0x00000048
Major runtime version: 0x0002
Minor runtime version: 0x0005
0x00003184 [0x00007078] address [size] of Metadata Directory:
Flags: 0x00000001
Entry point token: 0x00000000
0x00000000 [0x00000000] address [size] of Resources Directory:
0x00000000 [0x00000000] address [size] of Strong Name Signature:
0x00000000 [0x00000000] address [size] of CodeManager Table:
0x00000000 [0x00000000] address [size] of VTableFixups Directory:
0x00000000 [0x00000000] address [size] of Export Address Table:
0x00000000 [0x00000000] address [size] of Precompile Header:
When ran by the operating system, mscoree.dll
(or The Shim) is loaded, and it is the bootstrapper to clr.dll
and clrjit.dll
for .NET 4.0 and above, or mscordacwks.dll
and mscorjit.dll
for .NET 2.0 or below, which are the runtime and the JIT, respectively. You can see that the native dll entry point is instructed to be the _CorDllMain
method for a class library, and _CorExeMain
for an executable, which is responsible for the loading and jitting of the entry point. They, in turn, will call your applications entry point, in the managed environment.