Включить дополнительные файлы в сборку, используя MSBuild ProjectReference?

У меня есть библиотека классов, в которой есть несколько файлов, от которых она зависит, и эти файлы должны быть упакованы для развертывания с любым проектом, который зависит от этой библиотеки. В настоящее время это означает, что я должен настроить каждый из этих зависимых проектов, чтобы они копировали файлы, в дополнение к добавлению библиотеки в качестве MSBuild PrjectReference. Когда добавляется больше файлов, все проекты должны обновляться.

Я просматривал Microsoft.Common.targets для того, чтобы включить эти файлы с выводами собственного файла проекта библиотеки, поэтому любой проект, который имеет ProjectReference в библиотеке, автоматически получит файлы при выполнении сборки. Я еще ничего не получил, но мне любопытно, если это возможно. Похоже, что это должно быть, и цель _CopyFilesMarkedCopyLocal даже уважает элемент метаданных в противном случае - неиспользованный% (DestinationSubDirectory), который позволит настраивать размещение этих файлов, что было бы идеально.

Я считаю, что мне не хватает, для создания проекта A, который зависит от проекта B, который добавляет результаты проекта проекта B в элементы для сборки проекта A.

EDIT : комментарий Лео, я не заметил, что файлы, отмеченные с помощью CopyToOutputDirectory, также копируются в зависимые каталоги вывода проекта, потому что мы используем ItemGroups с именами, отличными от Content, EmbeddedResource, None и т. Д. Копаем глубже, целью, которая их использует, является GetCopyToOutputDirectoryItems и он рекурсивно вызывает задачу MSBuild для определения результатов проекта, поэтому я должен иметь возможность определять какую-то пользовательскую цель, которая может быть импортирована в наши проекты, которая добавляет наши пользовательские элементы в целевой объект GetCopyToOutputDirectoryItems, так что нам не нужно использовать Содержание / Нет и т. Д.

Однако целью, которая выполняет копирование, является _CopyOutOfDateSourceItemsToOutputDirectoryAlways, что, к сожалению, не относится к% (DestinationSubDirectory), и поэтому все эти файлы копируются напрямую в $ (OutDir).

Моя новая цель - посмотреть, есть ли способ добавить пользовательские файлы в ReferenceCopyLocalPaths ItemGroup зависимых проектов, чтобы они были скопированы вместо цели _CopyFilesMarkedCopyLocal, которая использует% (DestinationSubDirectory).

msbuild,visual-studio-2017,msbuild-15,msbuild-projectreference,

1

Ответов: 1


0

Добавляет настраиваемое действие сборки для ItemGroups в целевой среде Microsoft.Common.CurrentVersion.targets

Вышеупомянутое название должно быть ближе к цели bwerks. В качестве теста мы могли бы знать, что пользовательское действие сборки для ItemGroups не будет скопировано в каталог «Выход», поэтому нам нужно выполнить наше пользовательское действие сборки для цели _CopyOutOfDateSourceItemsToOutputDirectoryAlways.

Для этого откройте файл C:Program Files (x86)Microsoft Visual Studio2017EnterpriseMSBuild15.0BinMicrosoft.Common.CurrentVersion.targetsв папке MSBuild 15.0 _CopyOutOfDateSourceItemsToOutputDirectoryAlways(убедитесь, что у вас есть достаточные разрешения и создайте резервную копию), найдите цель _CopyOutOfDateSourceItemsToOutputDirectoryAlways:

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

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

</Copy>

Тогда мы могли бы знать, что исходный файл для копирования - это @(_SourceItemsToCopyToOutputDirectoryAlways)поиск _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>

введите описание изображения здесь

Надеюсь это поможет.

MSBuild, зрительно-студия-2017, MSBuild-15, MSBuild-projectreference,
Похожие вопросы