Assuming that:
- The C# source code below is compiled under .NET 2.0 (CLR 2.0); and
- The above application uses the
app.config
listed below; and - Only .NET 4.0 (CLR 4.0) is installed on the environment of the client executing the application,
then which version of .NET is internally loaded to execute the application on the client's environment?
Description
The console application below will simply show that its CLR version is v4.0.30319
in the console, but @Reed Copsey's answer of the stack (CLR 2.0 vs 4.0 performance?) shows that .NET 2.0 is loaded in this case. Moreover, at MSDN it says when useLegacyV2RuntimeActivationPolicy
is set to false false
:
Use the default activation policy for the .NET Framework 4 and later, which is to allow legacy runtime activation techniques to load CLR version 1.1 or 2.0 into the process.
It sounds like .NET 2.0 is loaded in spite of the app.config
having a .NET 4.0 configuration. Have I misunderstood anything?
Source
C# source code
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string version = Environment.Version.ToString();
Console.WriteLine(version);
}
}
}
app.config
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="false">
<supportedRuntime version="v4.0.30319"/>
</startup>
</configuration>
The bottom line is that under your scenario, you specified .Net 4 as your only supported runtime, so your app will load with CLR 4.
The CLR behavior with your program is exactly as designed:
When I run your test app with the
supportedRuntime
as v4.0, Process Explorer shows it loads mscorlib v4.0.30319.When I run with
supportedRuntime
as v2.0.50727, Process Explorer shows it loads mscorlilb v2.0.50727.When I run with no
supportedRuntime
element, Process Explorer shows it loads mscorlilb v2.0.50727.This blurb from Microsoft states that the
supportedRuntime
element defines the specific version on which your program runs:There are two separate elements at play, here. Only the
supportedRuntime
element applies to your scenario.The
supportedRuntime
element defines the CLR versions on which your app will run, in the preferred order. If you list supported runtimes, then those CLR versions will be used, going down the list from top to bottom until an installed CLR version is found. If you don't list support runtimes, then your program will run with the version of the CLR against which it was compiled.The
useLegacyV2RuntimeActivationPolicy
element applies only to mixed-mode assemblies --- programs or DLLs that contain managed (.Net) and unmanaged (native) code. Your sample program isn't a mixed-mode assembly. For mixed-mode assemblies, setting the value tofalse
(the default), or not setting it all, uses the new .Net 4 in-process side-by-side loading for mixed-mode assemblies, so your app can run with CLR 4, and load a mixed-mode assembly in the same process using CLR 1.0-2.0. Setting it totrue
essentially reverts to the previous functionality prior to .Net 4, where the in-process side-by-side functionality is disabled, and whatever CLR version is selected to run the app will attempt to load your mixed-mode assembly. The CLR version used to load the mixed-mode assembly will be whichever one is selected to run the app, based on which version was used to compile the app, and your listed supported runtimes, if any.There's an MSDN Magazine article and an MSDN article about .Net 4 loading and In-Process Side-by-Side (In-Proc SxS) execution for COM components, which also has an impact on your scenario without COM components. Prior to .Net 4, if you compiled your app with a version of the CLR, and that version wasn't available on the system at runtime, the app would automatically run on a newer version of the CLR if it was installed. As of .Net 4, apps now won't run with a newer version of the CLR unless you specify the newer version in the
supportedRuntimes
element.Here's a quote from the MSDN article:
Finally, if you're on Vista, Win7, Server 2008, Server 2008 R2, you automatically have CLR 2.0 installed. Therefore, if you were to remove your
supportedRuntimes
element, or change it to v2.0.50727, you might still have CLR 2.0 available as a runtime.