【问题标题】:Include additional files in build using MSBuild ProjectReference?使用 MSBuild ProjectReference 在构建中包含其他文件?
【发布时间】:2019-01-31 06:41:27
【问题描述】:

我有一个类库,它有几个依赖的文件,并且必须将这些文件打包以便与任何依赖此库的项目一起部署。现在这意味着除了将库添加为 MSBuild PrjectReference 之外,我还必须自定义每个依赖项目以确保它们复制文件。添加更多文件时,必须更新所有项目。

我一直在通过 Microsoft.Common.targets 寻找一种将这些文件包含在库自己的项目文件的输出中的方法,因此任何对库具有 ProjectReference 的项目都会在构建时自动获取文件.我还没有任何工作,但如果这可能的话,我会更普遍地好奇。看起来应该是这样,_CopyFilesMarkedCopyLocal 目标甚至尊重其他未使用的 %(DestinationSubDirectory) 元数据项,它允许自定义放置这些文件,这将是完美的。

我相信我缺少的是,对于构建依赖于项目 B 的项目 A,将项目 B 的项目输出添加到项目 A 的构建项目中的部分。

编辑:Leo 的评论,我没有注意到标有 CopyToOutputDirectory 的文件也被复制到依赖的项目输出目录,因为我们使用的 ItemGroups 名称不是 Content、EmbeddedResource、None 等。更深层次,使用这些的目标是 GetCopyToOutputDirectoryItems,它似乎递归调用 MSBuild 任务来确定项目输出,所以我应该能够定义一些可以导入到我们的项目中的自定义目标,在 GetCopyToOutputDirectoryItems 目标中添加我们的自定义 ItemGroups , 这样我们就不必使用 Content/None 等了。

但是,执行复制的目标是 _CopyOutOfDateSourceItemsToOutputDirectoryAlways,不幸的是它不尊重 %(DestinationSubDirectory),因此所有这些文件都直接复制到 $(OutDir)。

我的新目标是查看是否有某种方法可以将自定义文件添加到依赖项目的 ReferenceCopyLocalPaths ItemGroup 中,以便它们被 _CopyFilesMarkedCopyLocal 目标复制,该目标确实使用 %(DestinationSubDirectory)。

【问题讨论】:

  • 现在没时间检查,但您不能从 _CopyFilesMarkedCopyLocal 追溯负责列出要复制的文件的目标吗?我相当确定有一种方法可以挂钩,以从引用的项目中复制任意文件。
  • 为那些附加文件设置属性复制到输出目录 不适合您?如果将该属性设置为 Copy Always,MSBuild 会将其复制到输出目录,并且任何具有库的 ProjectReference 的项目都会在执行构建时自动获取输出文件夹中的文件。跨度>
  • 有趣!我已经用新信息编辑了 OP。
  • @bwerks,这个问题有什么更新吗?你解决了这个问题吗?如果没有,请告诉我有关此问题的最新信息吗?

标签: msbuild visual-studio-2017 msbuild-15 msbuild-projectreference


【解决方案1】:

为 _CopyOutOfDateSourceItemsToOutputDirectoryAlways 目标中的 ItemGroups 添加自定义构建操作

上面的标题应该更接近 bwerks 的目标。作为测试,我们可以知道 ItemGroups 的自定义构建操作不会复制到输出目录,因此我们需要将自定义构建操作复制到目标 _CopyOutOfDateSourceItemsToOutputDirectoryAlways

为此,打开MSBuild 15.0文件夹C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets中的文件Microsoft.Common.CurrentVersion.targets(确保你有足够的权限并备份),找到目标_CopyOutOfDateSourceItemsToOutputDirectoryAlways

<Copy
    SourceFiles = "@(_SourceItemsToCopyToOutputDirectoryAlways)"
    DestinationFiles = "@(_SourceItemsToCopyToOutputDirectoryAlways->'$(OutDir)%(TargetPath)')"
    ...
        >

  <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>

</Copy>

那么我们可以知道复制的源文件是@(_SourceItemsToCopyToOutputDirectoryAlways),在targets中搜索_SourceItemsToCopyToOutputDirectoryAlways这个,你会发现:

<ItemGroup>
  <_SourceItemsToCopyToOutputDirectoryAlways KeepMetadata="$(_GCTODIKeepMetadata)" Include="@(ContentWithTargetPath->'%(FullPath)')" Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
  <_SourceItemsToCopyToOutputDirectory       KeepMetadata="$(_GCTODIKeepMetadata)" Include="@(ContentWithTargetPath->'%(FullPath)')" Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
</ItemGroup>

可以知道源文件是@(ContentWithTargetPath),继续搜索目标中的ContentWithTargetPath,最后得到如下:

<AssignTargetPath Files="@(Content)" RootFolder="$(MSBuildProjectDirectory)">
  <Output TaskParameter="AssignedFiles" ItemName="ContentWithTargetPath" />
</AssignTargetPath>

因此,我们可以知道目标是如何将默认构建操作文件复制到输出目录的。

现在,转到我们的自定义构建操作,我们只需将自定义构建操作添加到ItemName="ContentWithTargetPath",因此在文件Microsoft.Common.CurrentVersion.targets中添加以下内容:

<AssignTargetPath Files="@(MyBuildAction)" RootFolder="$(MSBuildProjectDirectory)">
  <Output TaskParameter="AssignedFiles" ItemName="ContentWithTargetPath" />
</AssignTargetPath>

保存。

对于项目文件.csproj中的文件:

  <ItemGroup>
    <MyBuildAction Include="TextFile1.txt">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </MyBuildAction>
  </ItemGroup>

希望这会有所帮助。

【讨论】:

  • 这是对扩展 Microsoft.Common.targets 的有用了解。现在我正在尝试编写一个使用这种方法而不修改 Microsoft.Common.targets 的目标,因为我们无法对 Microsoft.Common.targets 本身进行源代码控制,并且会随着更高(和更早)的 VS 版本而改变。
  • 此外,由于这种方法将自定义文件注入到由 _CopyOutOfDateSourceItemsToOutputDirectoryAlways 复制的 ItemGroups 中,因此无法使用 DestinationSubDirectory,因为该目标在复制语句中没有确认它。看来我需要将我的文件注入 ReferenceCopyLocalPaths ItemGroup,但这个 ItemGroup 是由 ResolveAssemblyReference 任务设置的,它的文档没有太多细节。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
相关资源
最近更新 更多