私有设置对 MSBuild 项目文件中的 ProjectReference 有啥作用?
Posted
技术标签:
【中文标题】私有设置对 MSBuild 项目文件中的 ProjectReference 有啥作用?【英文标题】:What does the Private setting do on a ProjectReference in a MSBuild project file?私有设置对 MSBuild 项目文件中的 ProjectReference 有什么作用? 【发布时间】:2014-12-02 06:56:27 【问题描述】:前几天我在一个项目文件中看到了这个:
<ProjectReference Include="Foo\Bar\Baz.csproj">
<Project>A GUID HERE</Project>
<Name>Baz</Name>
<Private>False</Private> <!-- ??? -->
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
</ProjectReference>
ProjectReference
中的每个节点似乎都是不言自明的(引用的项目文件、GUID、在解决方案资源管理器中显示的名称,以及当前项目是否应该链接到引用的项目),Private
除外, Common MSBuild Project Items 页面没有记录这个值。 (有一个 Private
设置记录为 Reference
而不是 ProjectReference
- 但它有 Never
、Always
和 PreserveNewest
设置,不是真假)
这个设置有什么作用?
【问题讨论】:
就 MSBuild 而言,ProjectReference 是一个项目组(即列表),Private 是包含项目的项目元数据。您的问题的答案在于任何包含的内容。更笼统地说,它是什么特定类型的项目?也许用 csharp 标记你的问题。 我的意思是“导入”而不是“包含”。 @malexander:如果您取消删除它,我认为您的回答很好...... @Tom:当然,严格来说是这样。另一方面,ProjectReference
项目(至少)被 C# 和 C++ MSBuild 支持基础架构识别;看起来它主要在 Microsoft.Common.CurrentVersion.targets
文件中处理。
【参考方案1】:
我只想声明,当使用<MSBuild Projects="$(MSBuildProjectFullPath)" Targets="Publish" Properties="$(_MSBuildProperties)" />
和项目$(MSBuildProjectFullPath)
具有ProjectReference
s 具有<None><CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory></None>
时,<Private>false</Private>
(您可以应用于ProjectReference
s)可能不起作用
.我已经阅读了 https://github.com/dotnet/sdk/blob/master/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets 周围的源代码并找到了解决方案。您需要定义_GetChildProjectCopyToPublishDirectoryItems=false
,例如:<MSBuild Projects="$(MSBuildProjectFullPath)" Targets="Publish" Properties="TargetFramework=$(TargetFramework);_GetChildProjectCopyToPublishDirectoryItems=false" />
【讨论】:
【参考方案2】:Private
标记维护用户对 Visual Studio 引用文件夹中“复制本地”复选框的覆盖。这控制是否使用来自 GAC 的引用,或者是否将引用的程序集复制到构建目录。
虽然我找不到任何关于此效果的 MSDN 文档(令人惊讶的是),但从行为和应用它的from the comment in Microsoft.Common.CurrentVersion.targets:1742
可以明显看出:
这在MSDN > Common MSBuild project items 中有记录,从行为和应用它的from the comment in Microsoft.Common.CurrentVersion.targets:1742
可以明显看出:
<!--
============================================================
ResolveAssemblyReferences
Given the list of assemblies, find the closure of all assemblies that they depend on. These are
what we need to copy to the output directory.
[IN]
@(Reference) - List of assembly references as fusion names.
@(_ResolvedProjectReferencePaths) - List of project references produced by projects that this project depends on.
The 'Private' attribute on the reference corresponds to the Copy Local flag in IDE.
The 'Private' flag can have three possible values:
- 'True' means the reference should be Copied Local
- 'False' means the reference should not be Copied Local
- [Missing] means this task will decide whether to treat this reference as CopyLocal or not.
[OUT]
@(ReferencePath) - Paths to resolved primary files.
@(ReferenceDependencyPaths) - Paths to resolved dependency files.
@(_ReferenceRelatedPaths) - Paths to .xmls and .pdbs.
@(ReferenceSatellitePaths) - Paths to satellites.
@(_ReferenceSerializationAssemblyPaths) - Paths to XML serialization assemblies created by sgen.
@(_ReferenceScatterPaths) - Paths to scatter files.
@(ReferenceCopyLocalPaths) - Paths to files that should be copied to the local directory.
============================================================
-->
【讨论】:
如果缺少<Private>
,则它不等于True
。搜索“MSBuild CopyLocal 错误”。例如。见***.com/questions/1132243
@xmedeko,没错。我不确定@GPR 在哪里得到“如果不存在,则假定默认值为 True”,因为答案明确表示“[Missing] 意味着此任务将决定是否将此引用视为 CopyLocal”。大部分逻辑在msbuild\Reference.cs:949
是否有可能即使 <Private>
设置为 True
,如果应用程序不使用该引用,MSBuild 仍然不会在输出中包含该引用?这是我在本地得到的当前行为......
@Ninja,如果 MSBuild 无法找到引用的程序集,这种情况最常发生。如果不直接被代码使用,也可能编译成功。您可以使用procmon 或MSBuild detailed logging 进行故障排除
@Mitch 啊,我明白了。因为这是我所看到的,奇怪的行为...我的构建成功但即使我将<Private>
设置为True
也看不到 DLL...我在想这可能是另一个 MSBuild 优化?我不是 100% 确定它没有被代码使用——但这只是一个猜测,因为构建成功......以上是关于私有设置对 MSBuild 项目文件中的 ProjectReference 有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章
知道为啥 MSBuild 会突然开始对我的解决方案中的其他项目执行代码分析吗?
Docs-VisualStudio-MSBuild-MSBuild参考:常用的 MSBuild 项目项