在.net 4.0上执行应用程序时,在.net 2.0下编译

时间:2011-08-03 05:20:03

标签: c# .net .net-4.0 .net-2.0 version

假设:

  1. 下面的C#源代码是在.NET 2.0(CLR 2.0)下编译的;和
  2. 上述申请使用下面列出的app.config;和
  3. 在执行应用程序的客户端环境中仅安装了.NET 4.0(CLR 4.0),
  4. 然后在内部加载哪个版本的.NET来在客户端环境中执行应用程序?

    描述

    下面的控制台应用程序只会在控制台中显示其CLR版本为v4.0.30319,但@Reed Copsey对堆栈的回答(CLR 2.0 vs 4.0 performance?)表明在这种情况下加载了.NET 2.0。此外,在MSDN处,当useLegacyV2RuntimeActivationPolicy设置为false false时,它会显示:

      

    使用.NET Framework 4及更高版本的默认激活策略,   允许遗留运行时激活技术加载CLR   版本1.1或2.0进入流程。

    尽管app.config具有.NET 4.0配置,但听起来像是加载了.NET 2.0。我误解了什么吗?

    来源

    C#源代码

    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>
    

1 个答案:

答案 0 :(得分:38)

最重要的是,在您的方案中,您将.Net 4指定为唯一受支持的运行时,因此您的应用程序将加载CLR 4.

您的程序的CLR行为完全符合设计:

当我使用supportedRuntime作为v4.0运行测试应用程序时,Process Explorer会显示它加载mscorlib v4.0.30319。

当我使用supportedRuntime作为v2.0.50727运行时,Process Explorer显示它加载mscorlilb v2.0.50727。

当我运行没有supportedRuntime元素时,Process Explorer显示它加载mscorlilb v2.0.50727。

This blurb from Microsoft表示supportedRuntime元素定义了程序运行的特定版本:

  

默认情况下,应用程序在为其构建的.NET Framework版本上运行。如果该版本不存在且应用程序配置文件未定义支持的版本,则可能发生.NET Framework初始化错误。在这种情况下,运行应用程序的尝试将失败。

     

要定义运行应用程序的特定版本,请在应用程序的配置文件中添加一个或多个元素。每个元素都列出了运行时支持的版本,第一个指定了最喜欢的版本,最后一个指定了最不喜欢的版本。


这里有两个独立的元素。只有supportedRuntime元素适用于您的方案。

supportedRuntime元素按首选顺序定义应用程序将运行的CLR版本。如果列出支持的运行时,则将使用这些CLR版本,从上到下列表,直到找到已安装的CLR版本。如果您没有列出支持运行时,那么您的程序将使用与其编译的CLR版本运行。

useLegacyV2RuntimeActivationPolicy元素仅适用于混合模式程序集---包含托管(.Net)和非托管(本机)代码的程序或DLL。您的示例程序不是混合模式程序集。对于混合模式程序集,将值设置为false(默认值),或者不设置全部,使用新的.Net 4进程内并行加载混合模式程序集,因此您的应用程序可以使用CLR 4运行,并使用CLR 1.0-2.0在同一进程中加载​​混合模式程序集。将其设置为true基本上恢复到.Net 4之前的先前功能,其中禁用进程内并排功能,并且选择运行应用程序的任何CLR版本将尝试加载混合 - 模式组装。用于加载混合模式程序集的CLR版本将根据用于编译应用程序的版本以及列出的支持的运行时(如果有)来选择运行应用程序。


有一个MSDN Magazine article和一个MSDN article关于.COM 4加载和进程内并排(In-Proc SxS)执行COM组件,它还有一个没有COM组件对您的方案的影响。在.Net 4之前,如果您使用CLR版本编译应用程序,并且该版本在运行时无法在系统上运行,则应用程序将自动在较新版本的CLR上运行(如果已安装)。从.Net 4开始,除非您在supportedRuntimes元素中指定较新版本,否则应用程序现在不会使用较新版本的CLR运行。

以下是MSDN文章的引用:

  

应用程序开发人员。并行托管对应用程序开发人员几乎没有影响。默认情况下,应用程序始终针对它们构建的.NET Framework版本运行;这没有改变。但是,开发人员可以覆盖此行为并指示应用程序在较新版本的.NET Framework下运行(请参阅方案2)。

     

库开发人员和消费者。并行托管并不能解决库开发人员面临的兼容性问题。由应用程序直接加载的库(通过直接引用或通过Assembly.Load调用)继续使用它加载到的AppDomain的运行时。您应该针对要支持的所有.NET Framework版本测试库。如果使用.NET Framework 4运行时编译应用程序但包含使用早期运行时构建的库,则该库也将使用.NET Framework 4运行时。但是,如果您的应用程序是使用早期运行时和使用.NET Framework 4构建的库构建的,则必须强制您的应用程序也使用.NET Framework 4(参见方案3)。

最后,如果您使用的是Vista,Win7,Server 2008,Server 2008 R2,you automatically have CLR 2.0 installed。因此,如果要删除supportedRuntimes元素,或将其更改为v2.0.50727,则可能仍将CLR 2.0作为运行时提供。

.Net runtimes