How does Windows XP know to launch the proper .Net runtime when multiple .Net framework versions get installed
-
I've installed both .Net Framework v1.1 and v2.0 on my machine. Just wonder when I run a .Net Framework v1.1 application how does Windows XP know to launch .Net Framework v1.1 runtime for it, but not v2.0 runtime. I'd like to know the mechanism behind this. Since Windows XP itself has no knowledge about .Net, I guess that when .Net gets installed, it must hook something to the OS. BTW, since Vista come with .Net Framework v3.0, does Vista works in a different way from XP or actually the same? Thanks a lot.
-
I've installed both .Net Framework v1.1 and v2.0 on my machine. Just wonder when I run a .Net Framework v1.1 application how does Windows XP know to launch .Net Framework v1.1 runtime for it, but not v2.0 runtime. I'd like to know the mechanism behind this. Since Windows XP itself has no knowledge about .Net, I guess that when .Net gets installed, it must hook something to the OS. BTW, since Vista come with .Net Framework v3.0, does Vista works in a different way from XP or actually the same? Thanks a lot.
-
-
I've installed both .Net Framework v1.1 and v2.0 on my machine. Just wonder when I run a .Net Framework v1.1 application how does Windows XP know to launch .Net Framework v1.1 runtime for it, but not v2.0 runtime. I'd like to know the mechanism behind this. Since Windows XP itself has no knowledge about .Net, I guess that when .Net gets installed, it must hook something to the OS. BTW, since Vista come with .Net Framework v3.0, does Vista works in a different way from XP or actually the same? Thanks a lot.
Through some fun in the binary. Let's actually use Windows 2000 as the example as Windows XP knows a bit more. An executable contains an Import Address Table which the operating system loader fills in with the addresses of all DLLs that the executable references. It does this recursively with any DLLs that those DLLs depend on. Once it's finished doing this process, it then jumps to the Start Address that's listed in the executable's header. .NET applications have their Start Address field set to the address in the Import Address Table that the instruction to call _CorExeMain in mscoree.dll points to. So the program effectively starts up in _CorExeMain. mscoree.dll is one of the very few components of .NET that is shared between all versions. The version present is always from the newest version of .NET installed. It implements a pretty simple policy by default: if the application was built with .NET 1.1 and .NET 1.1 is installed, .NET 1.1 is used. Otherwise, .NET 2.0 is used. What mscoree.dll actually does is load mscorwks.dll from the specified version's folder and hand the program off to that. You can override the policy by adding a configuration file (MyApp.exe.config, if the program is MyApp.exe) and setting the
<supportedRuntime>
element to say which version of .NET should be used. I've used this for an unmanaged program to control the version of .NET used for COM components. Incidentally, ".NET 3.0" is just a set of new classes. The runtime, mscorwks.dll, is not updated after .NET 2.0 (except for .NET 2.0 SP1). It gets even more complicated for 64-bit operating systems, which are .NET-aware. Here, if the executable is compiled with /platform:x64, it gets a PE 2.0+ header indicating that a 64-bit process is required, and the 32-bit OS will reject it. If compiled with /platform:x86, it gets an original PE header indicating a 32-bit process (and a flag is set in the CLR header). However, an executable compiled with /platform:anycpu is compiled with an original PE header but runs in a 64-bit process on 64-bit Windows. I think this can only be done by the CreateProcess code recognising that it is a .NET executable and choosing to create a 64-bit process rather than a 32-bit one.DoEvents: Generating unexpected recursion since 1991
-
Through some fun in the binary. Let's actually use Windows 2000 as the example as Windows XP knows a bit more. An executable contains an Import Address Table which the operating system loader fills in with the addresses of all DLLs that the executable references. It does this recursively with any DLLs that those DLLs depend on. Once it's finished doing this process, it then jumps to the Start Address that's listed in the executable's header. .NET applications have their Start Address field set to the address in the Import Address Table that the instruction to call _CorExeMain in mscoree.dll points to. So the program effectively starts up in _CorExeMain. mscoree.dll is one of the very few components of .NET that is shared between all versions. The version present is always from the newest version of .NET installed. It implements a pretty simple policy by default: if the application was built with .NET 1.1 and .NET 1.1 is installed, .NET 1.1 is used. Otherwise, .NET 2.0 is used. What mscoree.dll actually does is load mscorwks.dll from the specified version's folder and hand the program off to that. You can override the policy by adding a configuration file (MyApp.exe.config, if the program is MyApp.exe) and setting the
<supportedRuntime>
element to say which version of .NET should be used. I've used this for an unmanaged program to control the version of .NET used for COM components. Incidentally, ".NET 3.0" is just a set of new classes. The runtime, mscorwks.dll, is not updated after .NET 2.0 (except for .NET 2.0 SP1). It gets even more complicated for 64-bit operating systems, which are .NET-aware. Here, if the executable is compiled with /platform:x64, it gets a PE 2.0+ header indicating that a 64-bit process is required, and the 32-bit OS will reject it. If compiled with /platform:x86, it gets an original PE header indicating a 32-bit process (and a flag is set in the CLR header). However, an executable compiled with /platform:anycpu is compiled with an original PE header but runs in a 64-bit process on 64-bit Windows. I think this can only be done by the CreateProcess code recognising that it is a .NET executable and choosing to create a 64-bit process rather than a 32-bit one.DoEvents: Generating unexpected recursion since 1991