7

安装 .Net 4.5 Beta 后,我的 Nant 构建的输出失败并显示:

“无法从程序集‘mscorlib,版本=4.0.0.0,文化=中性,PublicKeyToken=b77a5c561934e089’加载类型‘System.Runtime.CompilerServices.ExtensionAttribute’。”

因为正如在这个问题中回答的那样 ExtensionAttribute 已从 System.Core.dll 移至 mscorlib.dll。因此,尽管我在 nant 构建脚本中指定了目标框架,但 nant 构建正在合并 .net4.5 程序集,如下所示:

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

在 Visual Studio 下,构建工作正常(生成不需要 .Net 4.5 的 .dll)。但我需要构建与 nant 一起使用,因为我们有“老派”以及使用 nant 的构建过程。

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

4

3 回答 3

10

昨天我将 VS 2012 与 VS 2010 并排安装,在重新编译和部署 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 文件夹中“bad new”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 的主机上启动。:)

PS看起来微软重新发明了DLL HELL :)

于 2012-08-30T15:42:03.133 回答
1

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

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

同样,已经有一段时间了,我不能 100% 确定这会做到这一点,但它可能会让你走上正确的轨道。

于 2012-08-16T19:21:43.237 回答
1

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

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

  2. basedir="${environment::get-folder-path('ProgramFiles')}..." 对我不起作用,因为 NAnt.exe 是 64 位进程。实际上,大多数标准程序集仅在 Program Files (x86) 根目录下可用。我尝试对 NAnt.exe 进行标记,但这会导致其他问题。为了确保核心程序集可以被 32 位和 64 位进程定位,我创建了一个目录 C:\Nant\Microsoft.Net\v4.0 并将它们复制到那里。因为该目录不在Program Files 之下,所以它始终可见。

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

修改后的代码记录了对 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 '...
于 2014-03-26T14:32:30.863 回答