使用.NET 4.5(Beta)程序集引用的Nant构建尽管指定了“net-4.0”

时间:2012-08-16 16:12:43

标签: .net-4.0 nant .net-4.5 ilmerge

安装.Net 4.5 Beta后,我的Nant版本的输出失败了:

"could not load type 'System.Runtime.CompilerServices.ExtensionAttribute' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'."

因为正如question ExtensionAttribute was moved to mscorlib.dll from System.Core.dll所述。因此,尽管我在nant构建脚本中指定了目标框架,但是nant构建正在整合.net4.5程序集,如下所示:

<property name="nant.settings.currentframework" value="net-4.0" />

在Visual Studio下,构建工作正常(生成一个不需要.Net 4.5的.dll)。但我需要构建与nant合作,因为我们有&#34;老学生&#34;以及构建使用nant的进程。

我需要在我的nant构建脚本中添加什么才能使构建实际上坚持4.0?

3 个答案:

答案 0 :(得分:10)

昨天我与VS 2010并排安装了VS 2012,在重新编译和部署Web项目后,它失败并出现同样的异常。经过一小时的研究,我找到了解决方案。

首先,您需要编辑nant.exe.config

打开它并找到:

<framework
   name="net-4.0" 

这是约。在第555行(默认配置为NAnt 0.92)

你会看到一个巨大的xml,描述了net-4.0的编译。找到三个子<reference-assemblies>元素。前两个看起来像

<reference-assemblies basedir="${path::combine(installRoot, 'v4.0.30319')}">
<reference-assemblies basedir="${path::combine(installRoot, 'v4.0.30319')}/WPF">

,第三是

<reference-assemblies basedir="${environment::get-folder-path('ProgramFiles')}/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.0">

现在 - 只需编辑前两个以匹配第三个(从第三个复制并粘贴替换第一个和第二个)。在此之后,NAnt将在Reference Assemblies文件夹中查找所有.dll(而不是'破坏'Windows / Microsoft .NET /...)

不要担心第二个/WPF后缀 - Reference Assemblies所有文件都位于一个文件夹中,没有/ WPF子文件夹。

第二步 - 更改构建脚本

调用csc任务时,添加两个属性,nostdlibnoconfig

<csc target="..." output="..." nostdlib="true" noconfig="true" ...>

这将禁止从csc的文件夹中自动引用“坏新”mscorlib和其他库。

<references>元素内部 - 手动添加mscorlib.dll,system.core.dll和所有使用过的系统库。 NAnt会在Referenced Assemblies文件夹中找到它们:

<references>
    <include name="mscorlib.dll"/>
    <include name="Microsoft.CSharp.dll"/>
    <include name="System.dll"/>
    <include name="System.Configuration.dll"/>
    <include name="System.Core.dll"/>
    ...

之后(并重建当然)我的网站成功启动了使用“原始”.NET Framework 4的托管计算机。:)

P.S。看起来微软重新发明了DLL HELL:)

答案 1 :(得分:1)

你可能需要做两件事(我根本没有尝试过,但我记得它在4发布时有所帮助)。首先,修改nant.exe.config并将版本添加到配置文件的启动部分中支持的框架版本(我认为这是他们去的地方,一旦打开它就应该很明显)。然后,升级到最新最好的NaNT版本。然后,在构建文件中执行以下操作:

<property 
    name="assembly-location" value="${framework::get-assembly-directory('net-4.5')}" />
<property 
    name="dotNetReferenceAssemblyPath" value="${assembly-location}\" />

同样,它已经有一段时间了,我不是百分之百确定这会做到这一点,但它可能会让你走上正轨。

答案 2 :(得分:1)

基本上,Dmitry的解决方案是正确的,但我必须在我的Windows Server 2012上编译.Net 4.0程序集之前稍微修改它。我使用了最新的nant-0.93-nightly-2013-10-20在我的环境中。

  1. 在Visual Studio 2013构建输出中,可以看到CSC使用/ noconfig和/ nostdlib +标志执行.Net 4.0目标。这证明您的解决方案是有效的。

  2. BASEDIR =&#34; $ {环境::获得文件夹路径(&#39; PROGRAMFILES&#39;)} ...&#34;对我不起作用,因为NAnt.exe是64位进程。实际上,大多数标准程序集仅在Program Files(x86)根目录下可用。我试过corflagging NAnt.exe,但这引起了其他问题。为了确保可以通过32位和64位进程定位核心程序集,我创建了一个目录C:\ Nant \ Microsoft.Net \ v4.0并将其复制到那里。由于目录在Program Files下面,因此它始终可见。

  3. 我们的NAnt构建脚本非常庞大,我不想手动修改每个csc任务的引用。为了减少对脚本的必要修改,我稍微定制了NAnt 0.93。如果目标框架名称为&#34; net-4.0&#34;并且任务是CscTask类型,它自动添加mscorlib.dll,System.dll和位于csc任务源根目录中的csproj中的所有System asembly引用。可以在此处找到自定义的源代码和二进制文件: http://support.decos.nl/berend/NAnt-0.93-nightly-2013-10-20-modified.zip

  4. 修改后的代码记录了对NAnt构建输出的添加引用:

    Inserted reference System.Data.dll
    Inserted reference System.Xml.dll
    Inserted reference System.configuration.dll
    Inserted reference System.dll
    Inserted reference mscorlib.dll
          [csc] Compiling 11 files to '...