从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更新期间将标志OnlyReferenceAndBuildProjectsEnabledInSolutionConfiguration
从false
更改为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文件时存在的错误,并且在新创建的项目中不再存在。
根据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库。