msbuild - 如果未签名的 dll 的版本低于项目依赖项之一的要求,msbuild 拒绝复制它 - 这是设计使然吗?
问题描述
我有以下情况:
- 所有涉及的 dll 均未签名
- 解决方案中的所有项目都依赖于 Shared.dll 的 1.0.21221.1 版本
- 解决方案中某些项目的一些NuGet依赖依赖于同一个dll的1.0.21237.1版本。
- 构建 Web 应用程序时(让我们将其命名为Api),预计会将 Shared.dll 从文件夹复制
$(OutDir)
到该$(OutDir)_PublishedWebsites\Api\bin
文件夹。中找到的 Shared.dll$(OutDir)
版本为 1.0.21221.1。 - 未复制 Shared.dll,Web 应用程序无法运行。
这是来自二进制日志的证据:
图表 A - 版本冲突:
图表 B - ResolveAssemblyReference 指示不要复制 Shared.dll:
我知道 msbuild 不喜欢版本冲突的想法,但不复制 dll 会产生一个彻头彻尾的错误,因为应用程序无法启动。
我知道可以通过添加程序集绑定重定向来解决它。但我认为未签名的程序集没有必要。我理解错了还是我错过了什么?
编辑 1
以下是我对评论中发布的问题的回答:
(不幸的是我被要求混淆一些关键字,我不知道为什么)
- Api 项目究竟是如何引用 Shared.dll 的?
正如我们在展览中看到的那样,B Shared.dll 是 Api 的传递依赖项。实际上,Api 依赖于 Xyz.BusinessApi,如下所示:
<Reference Include="Xyz.BusinessAPI" />
现在 DLL 通过各自的 NuGet 依赖项依赖 Shared.dll,下面是 Xyz.BusinessAPI 的 project.assets.json 文件的片段:
- 还有哪些其他项目引用 Shared.dll 以及如何引用?
在 1.0.21221.1 版本中有很多项目将其作为 NuGet 包进行引用。问题是一些项目还引用了另外两个 NuGet 包,它们又依赖于同一个 NuGet 包的 1.0.21237.1 版本。这在 RAR 输出中显示 - 请参见附录A。
我想强调 - 没有项目将 Shared.dll 作为原始 dll 引用,只能作为 NuGet 包或通过其他 NuGet 或项目或项目 dll间接引用。项目 dll 是来自以前构建的解决方案的项目的 dll - 我们不允许项目引用其他解决方案,因此如果项目是在以前的解决方案中构建的,那么它将在后续解决方案中被引用为 DLL。
- 从 OutDir 复制到 _PublishedWebsites\api\bin 的机制是什么?
这是_CopyFilesMarkedCopyLocal
来自 C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VisualStudio\v16.0\WebApplications\Microsoft.WebApplication.targets 的标准 Web 应用程序发布目标:
<!-- copy any referenced assemblies to _PublishedWebsites\app\bin folder -->
<Copy SourceFiles="@(ReferenceCopyLocalPaths)"
DestinationFiles="@(ReferenceCopyLocalPaths->'$(WebProjectOutputDir)\bin\%(DestinationSubDirectory)%(Filename)%(Extension)')"
SkipUnchangedFiles="true"
Retries="$(CopyRetryCount)"
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"/>
- Shared.dll 如何在 OutDir 中结束?
我们所有的代码都内置在共享的 bin 目录中——我们OutDir
为所有项目设置了相同的值。因此,所有项目二进制文件及其依赖项,包括 Shared.dll 都首先出现在此处。
- binlog中是否有双重写入?
解决方案
简短的回答是您的项目间接依赖于 Shared.dll 的两个版本:1.0.21221.1
和 1.0.21237.1
.
RAR(MSBuild ResolveAssemblyReference 任务)检查了所有 .dll 的所有引用并找到了这两个版本。它报告了一个冲突:
注意它如何在方括号中报告 Shared.dll 21221 找到的文件路径,并为 21237 报告 [](表示未找到该版本的文件)。
There was a conflict under($rar)
使用或搜索这些很有用$warning under($rar)
。
现在,OutDir 只包含 Shared.dll 21221,因此无法在任何地方找到版本为 21237 的 Shared.dll。
诀窍是搜索Shared.dll under($rar project(api.csproj))
你会发现来自 RAR 的相关消息:
Considered "C:\Xyz\61\bin.link\Shared.dll",
but its name "Shared, Version=1.0.21221.1, Culture=neutral, PublicKeyToken=null"
didn't match the expected name "Shared, Version=1.0.21237.1, Culture=neutral, PublicKeyToken=null".
所以,它看到了冲突,决定统一在更高版本(21237)上,但没有找到那个版本的文件。所以 21221 的引用不是 CopyLocal 因为它没有在那个版本上统一,并且对 21237 的引用没有被解析,因为没有找到那个版本的文件。
要解决此问题,我建议添加对版本 21237 的 Shared.dll 的显式引用(通过 NuGet 或通过GeneratePathProperty
包引用上的元数据:https ://docs.microsoft.com/en-us/nuget/consume-packages/ package-references-in-project-files#generatepathproperty)。如果您使用 GeneratePathProperty,则可以直接使用$(PkgFoo_Bar)\lib\net472\Shared.dll
或类似方法引用 .dll。还要添加从 21221 到 21237 的绑定重定向以解决冲突。一旦正确的版本 (21237) 将在您的 OutDir 中,它将被正确复制到输出。
希望这可以澄清。
推荐阅读
- flutter - Admob 未在测试设备上显示生产广告(使用颤振)
- asp.net - C# BasicAuthentication 实现方式
- angular - Angular:在 ngOnInit() 中,当我重新加载组件时,我的 rxjs 函数不运行
- amazon-web-services - 将 ASP.NET Core Web API 发布到 AWS 无服务器 Lambda 时出错:“policyArn”处的“AWSLambdaFullAccess”...成员的长度必须大于
- math - Coq 无法在 `match` 中推断类型参数
- sql - 如何避免配置单元查询中的重复
- r - 在 R 中,如何返回一行中的第 n 个最大数并将结果输出到新列,每行重复?
- python - 从 .txt 文件中读取文本并使用 python 插入字符串
- asp.net - 使用 .net core 和 razor,如何从静态页面导航回 asp 菜单
- python - 如何将 Django 表单字段名称列表传递给模板?