我们有一个.Net 3.5应用程序,它是使用一些调用msbuild.exe
最近我们所有的机器都开始自动从.Net 4.0更新到.Net 4.5作为公司范围内的政策的一部分,我们的构建脚本开始失败。
给出的错误是他们找不到引用的程序集,如下所示:
error CS0012: The type 'System.Drawing.Image' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
在每种情况下,我们都会尝试构建项目A,其中包含对项目B的引用,项目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
才能构建。
但无论出于何种原因,当使用msbuild 4.0或VS 2010进行构建时,这个限制对于我们的项目似乎并不重要。在没有引用System.Drawing.Image
的情况下构建ProjectA非常乐意。
即使在更新到.Net 4.5后,我仍然可以从Visual Studio 2010成功构建ProjectA
而不添加对System.Drawing.Image
的引用,但是现在使用msbuild构建(正确吗?)会失败。在VS 2012 Express中构建时,我也会收到引用错误,因此在VS的较新版本中,显然已经修复了允许这种情况发生的任何内容。
目前,我已经完成了我们解决方案中的所有148个项目并修复了所有引用,但是我想打开这个问题,试着找到为什么我能够使用msbuild构建ProjectA
的答案4.0或Visual Studio 2010,但未引用System.Drawing.Image
。
我已经确定我不能轻易地重现测试项目中的行为,所以我最好的猜测是它的一些配置,构建脚本的某些部分,或者它是一个存在的错误创建.sln或.csproj文件时,新创建的项目不再存在。
答案 0 :(得分:1)
基于Hans' comment,听起来在版本4和版本5之间的内部C#编译器中发生了一些变化,以修复允许我们在没有适当引用的情况下构建ProjectA
的错误。
这与MSBuild没有任何关系,改变的是您正在使用不同的C#编译器。版本5而不是4.我在其他问题中看到了粗略的证据,这些证据对于想要解决间接类型引用更为积极。没有什么可以钉在墙上,每个人都只是用明显的解决方案来解决这个问题。
查看msbuild.exe
日志时,我看到它归结为对csc.exe
的调用,该调用包含完全相同的/reference
列表,但是在4.5中失败。
使用4.0构建ProjectA
Task "Csc" c:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig /nowarn:1701,1702 /nostdlib+ /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 Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Web.Services.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /debug:pdbonly /filealign:512 /keyfile:ProjectA.snk /optimize+ /out:obj\Release\ProjectA.dll /target:library Properties\AssemblyInfo.cs SomeFile.cs Properties\VersionInfo.cs Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1 Copyright (C) Microsoft Corporation. All rights reserved. Done executing task "Csc".
使用4.5
构建ProjectATask "Csc" (TaskId:5812) C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig /nowarn:1701,1702 /nostdlib+ /errorreport:prompt /warn:4 /define:TRACE /highentropyva- /reference:C:\Path\bin\Release\ProjectB.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Web.Services.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /debug:pdbonly /filealign:512 /keyfile:ProjectA.snk /optimize+ /out:obj\Release\ProjectA.dll /target:library /utf8output Properties\AssemblyInfo.cs SomeFile.cs Properties\VersionInfo.cs (TaskId:5812) Microsoft (R) Visual C# Compiler version 4.0.30319.18408 (TaskId:5812) (TaskId:5812) for Microsoft (R) .NET Framework 4.5 (TaskId:5812) Copyright (C) Microsoft Corporation. All rights reserved. (TaskId:5812) (TaskId:5812) SomeFile.cs(32,18): error CS0012: The type 'System.Drawing.Image' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. [C:\Path\ProjectA.csproj] c:\Path\bin\Release\ProjectB.dll: (Location of symbol related to previous error) (TaskId:5812) The command exited with code 1. (TaskId:5812) Done executing task "Csc" -- FAILED. (TaskId:5812)
我希望有人能够解释这是什么,以及我如何重现这个&#34; bug&#34;使用4.0,但它看起来不容易回答这个问题。
答案 1 :(得分:0)
如果我不得不猜测,我会说它不能再找到的所有引用都是版本2.0.0.0。我们最近在这里遇到了类似的问题,我们不得不更新对于4.0.0.0版本的System。*和mscorlib以及类似引用的引用。
如果您无法替换引用并且BindingRedirects不是一个选项,请尝试手动将v2.0.0.0添加到您的bin文件夹。
最后,您可以使构建输出详细,以查看它在哪里寻找这些引用,它可能会指导您找到解决方案。
答案 2 :(得分:0)
也许当它更新它没有更新你的运行时设置架构时,特别是<probing>
元素告诉.Net搜索程序集的路径:
例如
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;bin2\subbin;bin3"/>
</assemblyBinding>
</runtime>
</configuration>
答案 3 :(得分:0)
Rachel,升级后,您对System.Drawing项目的任何机会参考都设置为SpecificVersion = true
?
另外,您是否在库项目中使用任何预编译的resx文件? 尝试右键单击.resx文件,然后选择“运行自定义工具”&#39;再次重做参考文献。
对于我最后一次尝试帮助您,您可以尝试在主项目配置中使用useLegacyV2RuntimeActivationPolicy="true"
并尝试使用旧版System.Drawing库。