从4.0升级到4.5后,MSBuild再也找不到依赖项

本文关键字:找不到 依赖 MSBuild 0升 | 更新日期: 2023-09-27 18:28:16

我们有一个.Net 3.5应用程序,它是使用一些调用msbuild.exe 的脚本构建的

最近,作为公司范围政策的一部分,我们所有的机器都开始自动从.Net 4.0更新到.Net 4.5,我们的构建脚本开始失败。

给出的错误是他们找不到引用的程序集,如下所示:

错误CS0012:在未引用的程序集中定义了类型"System.Drawing.Image"。必须添加对程序集"System.Drawing,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"的引用。

看起来在每种情况下,我们都试图构建引用了项目B的项目A,而项目B引用了库X,并得到一个错误,即项目A需要引用库X。

一个临时的解决方法是卸载4.5,卸载4.0,然后重新安装4.0,但这很耗时,在更新通常是静默和自动的环境中并不实用。

我已经尝试过使用以下msbuild交换机,但没有运气

  • /toolsversion:3.5-未定义Func的异常
  • /toolsversion:4.0-由于4.5替换了4.0工具而不起作用
  • /p:TargetFrameworkVersion="v3.5"-相同错误
  • /p:VisualStudioVersion=11.0-相同错误*`在csproj文件中-已存在,并且出现相同错误

.csproj文件已经在我的解决方案中的每个csproj文件中指定了<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>ToolsVersion="4.0"

我还尝试过将TargetFrameworkVersion更改为4.0,但这也不起作用。

我在网上发现了一些关于Microsoft在4.0到4.5更新期间将标志OnlyReferenceAndBuildProjectsEnabledInSolutionConfigurationfalse更改为true的说明,但在csproj文件中手动设置该标志也不能解决问题。

<OnlyReferenceAndBuildProjectsEnabledInSolutionConfiguration>
    false
</OnlyReferenceAndBuildProjectsEnabledInSolutionConfiguration>

为什么msbuild在从4.0升级到4.5后找不到这些子程序集,我该如何修复?

更新

我终于找到了问题的根源,但我不知道这是怎么发生的。

ProjectA有一个继承自ProjectB中抽象类的类,并且ProejctB.BaseClass的属性之一的类型为System.Drawing.Image

namespace ProjectA
{
    public class SomeClass : BaseClass { }
}
namespace ProjectB
{
    public abstract class BaseClass
    {
        public System.Drawing.Image GetImage() { };
    }
}

从我在网上读到的所有内容,以及创建自己的测试项目来看,这意味着ProjectA需要引用System.Drawing.Image才能构建。

但无论出于何种原因,当使用msbuild4.0或VS2010构建时,这种限制似乎对我们的项目无关紧要。在不引用System.Drawing.Image的情况下构建ProjectA是非常愉快的。

即使在更新到.Net 4.5之后,我仍然可以在不添加对System.Drawing.Image的引用的情况下从Visual Studio 2010成功构建ProjectA,但是现在使用msbuild构建(正确吗?)失败了。在VS 2012 Express中构建时,我也会遇到参考错误,所以允许这种情况发生的原因显然已经在较新版本的VS中得到了修复。

目前,我已经浏览了我们解决方案中的所有148个项目,并修复了所有引用,但我想让这个问题悬而未决,试着回答为什么我能够在不引用System.Drawing.Image的情况下使用msbuild 4.0或Visual Studio 2010构建ProjectA

我已经确定,我无法在测试项目中轻松地再现这种行为,所以我的最佳猜测是,它要么是一些配置,要么是构建脚本的某个部分,要么是创建.sln或.csproj文件时存在的错误,并且在新创建的项目中不再存在。

从4.0升级到4.5后,MSBuild再也找不到依赖项

根据Hans的评论,内部C#编译器在版本4和版本5之间似乎发生了一些变化,以修复允许我们在没有适当引用的情况下构建ProjectA的错误。

这与MSBuild无关,改变的是您使用了不同的C#编译器。版本5而不是版本4。我在其他问题中看到了一些粗略的证据,这些证据对想要解决间接类型引用更为激进。没有什么可以钉在墙上的,每个人都只是用显而易见的解决方案来解决这个问题。

当查看msbuild.exe日志时,我可以看到它归结为对csc.exe的调用,其中包含完全相同的/reference列表,但以4.5失败。

使用4.0 构建ProjectA

任务"Csc"c: ''Windows''Microsoft.NET''Framework''v4.0.30119''Csc.exe/noconfig/nowarn:17011702/nostlib+/errorreport:prompt/warn:4/define:TRACE/reference:c:''Path''bin''Release ''ProjectB.dll/reference:c:''Windows''Microsoft.NET''Framework ''v2.0.50727''mscorlib.dll/reference:"c:''Program Files(x86)''reference Assemblys''Microsoft''Framework'' v3.5''System.Core.dll"/reference:"c:''Program File(x86)''Reference Assemblys''Microsoft''Framework''v3.5''System.DataDataSetExtensions.dllFiles(x86)''Reference Assemblys''Microsoft''Framework''v3.5''System.Xml.Linq.dll"/debug:pdbonly/filealign:512/keyfile:ProjectA.snk/poptimity+/out:obj''Release ''ProjectA.dll/target:library Properties ''AssemblyInfo.cs SomeFile.cs Properties ''VersionInfo.csMicrosoft(R)Visual C#2010编译器4.0.30319.1版版权所有(C)Microsoft Corporation。保留所有权利。完成执行任务"Csc"。

使用4.5 构建ProjectA

任务"Csc"(任务ID:5812)C: ''Windows''Microsoft.NET''Framework''v4.0.30119''Csc.exe/noconfig/nowarn:17011702/nostdlib+/errorreport:prompt/warn:4/define:TRACE/heightopyva-/reference:C:''Path''bin''Release ''ProjectB.dll/reference:C:''Windows''Microsoft.NET''Framework ''v2.0.50727''mscorlib.dll/reference:"C:''Program Files(x86)''reference Assemblys''Microsoft''Framework ''v3.5''System.Core.dll"/reference:"C:''Program File(x86)''Reference Assemblys''Microsoft''Framework''v3.5''System.DataDataSetExtensions.dllFiles(x86)''Reference Assemblys''Microsoft''Framework''v3.5''System.Xml.Linq.dll"/debug:pdbonly/filealign:512/keyfile:ProjectA.snk/poptimity+/out:obj''Release ''ProjectA.dll/target:library/utf8output Properties ''AssemblyInfo.cs SomeFile.cs Properties ''VersionInfo.cs(TaskId:5812)Microsoft(R)Visual C#编译器4.0.30319.18408版(任务ID:5812)(任务ID:5812)适用于Microsoft(R).NET Framework 4.5(任务ID:5812)版权所有(C)Microsoft Corporation。保留所有权利。(任务ID:5812)(任务ID:5812)SomeFile.cs(32,18):错误CS0012:在未引用的程序集中定义了类型"System.Drawing.Image"。必须添加对程序集"System.Drawing,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"的引用。[C:''Path''ProjectA.csproj]c: ''Path''bin''Release ''ProjectB.dll:(与上一个错误相关的符号的位置)(TaskId:5812)命令已退出,代码为1。(任务ID:5812)完成执行任务"Csc"--失败。(任务ID:5812)

我希望这里有人能解释这是什么,以及我如何用4.0重现这个"bug",但这个问题看起来并不容易回答。

如果非要我猜测的话,我会说它无法再定位的所有引用都是2.0.0.0版本。我们最近遇到了一个类似的问题,我们不得不将引用更新为System.*和mscorlib的4.0.0.0版本以及类似的引用。

如果无法替换引用,并且BindingRedirects不是一个选项,请尝试手动将v2.0.0.0添加到bin文件夹中。

最后,您可以使构建输出变得详细,以查看它在哪里查找这些引用,这可能会指导您找到解决方案。

当它更新它时,它可能不会更新您的运行时设置架构,特别是告诉.Net要搜索程序集的路径的<probing>元素:

例如。

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="bin;bin2'subbin;bin3"/>
      </assemblyBinding>
   </runtime>
</configuration>

请参阅:http://msdn.microsoft.com/en-us/library/microsoft.build.tasks.assignprojectconfiguration.onlyreferenceandbuildprojectsenabledinsolutionconfiguration%28v=vs.121%29.aspx

Rachel,您的系统上有任何可能的参考。升级后,项目图纸设置为SpecificVersion = true

此外,您是否在库项目中使用任何预编译的resx文件?尝试右键单击.resx文件,然后再次选择"运行自定义工具"以重做引用。

在我最后一次尝试帮助您时,您可以尝试在主项目配置中使用useLegacyV2RuntimeActivationPolicy="true",并尝试使用传统的System.Drawing库。