Eir*_*ske 12 c# msbuild teamcity json.net asp.net-web-api
我正在使用TeamCity中的MSBuild运行器来构建ASP.net web api并运行单元测试.一切正常,直到我升级到"Microsoft Build Tools 2017 15.7.2".
突然,msbuild从"C:\ Program Files(x86)\ ISS\Microsoft Web Deploy V3"或"C:\ Program Files\ISS\Microsoft Web"复制旧版本的Newtonsoft.Json.dll(版本6.0.4.17603)在构建解决方案时将V3"部署到输出文件夹.所有项目都使用NuGet引用9.0.1版本.
在构建运行时监视输出文件夹,我可以看到.dll在6.0.4和9.0.1之间来回切换,直到构建结束,并且6.0.4版本仍然存在.
我发现了这个问题,当我将Web部署文件夹中的Newtonsoft.Json.dll文件重命名为Newtonsoft.Json_old.dll时,msbuild没有替换我的9.0.1版本,一切正常.
我已经检查过引用Newtonsoft.Json的所有项目都引用了9.0.1版本并在.csproj文件中使用了正确的Hint-Path.
有谁知道如何解决这个问题?我的解决方案似乎更像是一种解决方法,我想知道为什么msbuild首先复制这个文件.
摘要
当MSBuild解析程序集时,它会根据您所安装的内容在一些非常奇怪的目录中进行搜索,包括该Web Deploy文件夹。基于MSBuild参考,我认为这是遗留行为。您可以使用项目文件中定义的MSBuild属性来阻止该操作。
在受影响的项目文件中,找到以下行:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Run Code Online (Sandbox Code Playgroud)
并将其添加到它下面:
<PropertyGroup>
<AssemblySearchPaths>$(AssemblySearchPaths.Replace('{AssemblyFolders}', '').Split(';'))</AssemblySearchPaths>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)
这将导致MSBuild在解析程序集时不再在有问题的文件夹中查找。
全文
当我们移至Visual Studio 2019时,我的团队遇到了类似的问题。我们的某些项目仍以.NET Framework 4.0为目标,并且在我们的构建代理上安装Visual Studio 2019之后,我们开始在引用了某些项目的项目中遇到一个神秘的错误。我们的核心库:
无法解析主要参考“ OurCoreLibrary,版本= 3.4.2.0,文化=中性,PublicKeyToken = xxxxxxxxxxxxxxxx,processorArchitecture = MSIL”,因为它间接依赖程序集“ Newtonsoft.Json,版本= 9.0.0.0,Culture =中性的,PublicKeyToken = 30ad4fe6b2a6aeed”,它是针对“ .NETFramework,Version = v4.5”框架构建的。此版本比当前目标框架“ .NETFramework,Version = v4.0”更高。
在将项目切换到目标4.5时问题就消失了,但是由于我不会进入这里的原因,我们无法为每个受影响的项目都这样做,所以我决定更深入地研究。
事实证明,您的问题为您提供了一些有关正在发生的事情的见解。我们所引用的Newtonsoft.Json版本与“ C:\ Program Files(x86)\ ISS \ Microsoft Web Deploy V3”中的版本匹配,当我删除该文件时,构建成功。
我们的特定问题是Web Deploy文件夹中的Newtonsoft.Json副本是相同版本(9.0.0.0),但框架错误(4.5而不是4.0),并且由于某种原因,解析逻辑不会检查目标框架,在构建时导致不匹配。更新到VS2019涉及更新Web Deploy,这也将Newtonsoft.Json的副本更新到9.0.0.0,从而导致我们的冲突。
要了解为什么甚至要从头开始查看该程序集,我将MSBuild项目的生成输出详细程度设置为Diagnostic,并查看发生了什么。搜索有问题的路径表明,在ResolveAssemblyReferences任务中,MSBuild正在通过一些意外的地方来查找匹配项:
1> For SearchPath "{AssemblyFolders}". (TaskId:9)
1> Considered "C:\Program Files (x86)\Microsoft.NET\ADOMD.NET\140\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Microsoft.NET\ADOMD.NET\140\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Microsoft.NET\ADOMD.NET\140\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files\IIS\Microsoft Web Deploy V3\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files\IIS\Microsoft Web Deploy V3\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files\IIS\Microsoft Web Deploy V3\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
Run Code Online (Sandbox Code Playgroud)
进一步的挖掘显示,搜索到的路径以传递,该路径AssemblySearchPaths在Microsoft.Common.CurrentVersion.targets中定义:
<AssemblySearchPaths Condition=" '$(AssemblySearchPaths)' == ''">
{CandidateAssemblyFiles};
$(ReferencePath);
{HintPathFromItem};
{TargetFrameworkDirectory};
$(AssemblyFoldersConfigFileSearchPath)
{Registry:$(FrameworkRegistryBase),$(TargetFrameworkVersion),$(AssemblyFoldersSuffix)$(AssemblyFoldersExConditions)};
{AssemblyFolders};
{GAC};
{RawFileName};
$(OutDir)
</AssemblySearchPaths>
Run Code Online (Sandbox Code Playgroud)
根据MSBuild任务参考中的ResolveAssemblyReferences任务,SearchPaths参数定义为:
指定搜索目录或特殊位置以查找磁盘上代表程序集的文件。搜索路径的列出顺序很重要。对于每个程序集,从左到右搜索路径列表。找到代表程序集的文件后,该搜索将停止,并开始搜索下一个程序集。
...并定义了一些特殊的常量,包括我们的朋友{AssemblyFolders}:
- {AssemblyFolders}:指定任务将使用Visual Studio.NET 2003从注册表中查找组件。
因为目录是按顺序检查的,所以您可能希望{HintPathFromItem}优先,并且在大多数情况下会这样。但是,如果您依赖于Newtonsoft.Json的较旧版本,则该版本将没有HintPath ,因此它将继续解决。
稍后在Microsoft.Common.CurrentVersion.targets中,我们可以看到在某些情况下显式删除了此常数,这就是上面的答案来自于:
<PropertyGroup Condition="'$(_TargetFrameworkDirectories)' == '' and '$(AssemblySearchPaths)' != '' and '$(RemoveAssemblyFoldersIfNoTargetFramework)' == 'true'">
<AssemblySearchPaths>$(AssemblySearchPaths.Replace('{AssemblyFolders}', '').Split(';'))</AssemblySearchPaths>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)
删除此常量会从考虑中删除有问题的文件夹,并且老实说,我无法想到一种情况,即我希望程序集隐式解析为在Web Deploy或SQL Server SDK中闲逛的任何版本,例如Newtonsoft.Json。夹。话虽这么说,我敢肯定有一个案例,将其关闭会导致某些问题,因此请记住这一点。
| 归档时间: |
|
| 查看次数: |
898 次 |
| 最近记录: |