Задача MSBuild Copy + пакетная обработка по метаданным корреляции

Я пытаюсь создать цель MSBuild, которая заключается в том, чтобы поместить определенный файл в список каталогов, а затем скопировать этот файл с другим именем в тот же каталог. Имя "назначения" напрямую зависит от каталога.

Давайте проиллюстрируем на примере:

|-\Source\MySolution.ProjectFoo\
|    -- App.config.tpl
|    -- MySolution.ProjectFoo.exe
|    -- (Target) MySolution.ProjectFoo.exe.config.tpl
|-\Source\MySolution.ProjectBar\
|    -- App.config.tpl
|    -- MySolution.ProjectBar.exe
|    -- (Target) MySolution.ProjectBar.exe.config.tpl

Я начал строить свой ItemGroup как это:

<ItemGroup>
    <AppConfigTemplates Include="Source\**\App.config.tpl">
        <Correlate>%(RecursiveDir)</Correlate>
    </AppConfigTemplates>
    <ExeFiles Include="Source*\**\*.exe">
        <Correlate>%(RecursiveDir)</Correlate>
    </ExeFiles>
</ItemGroup>

Я надеялся, что смогу дозировать Correlate свойство метаданных. Что-то вроде:

<Copy Batch="%(Correlate)" SourceFiles="%(AppConfigTemplates.FullPath)"
                           DestinationFiles="%(ExeFiles.FullPath).config.tpl" />

Как мне этого добиться?

1 ответ

Решение

Можно было бы "коррелировать" отдельные группы элементов подобным образом, но вам все равно нужно убедиться, что они имеют одинаковое количество элементов в одном и том же порядке (например, что, если есть exe, но нет.tpl и наоборот), что, вероятно, станет грязным. Более простое решение - просто перечислить исполняемые файлы и скопировать файл tpl (который имеет фиксированное имя), если он существует:

<ItemGroup>
  <ExeFiles Include="Source\**\*.exe">
    <!-- expected location of the tpl: same directory -->
    <AppConfigTpl>%(RootDir)%(Directory)App.config.tpl</AppConfigTpl>
  </ExeFiles>
</ItemGroup>

<Target Name="CopyTpl">
  <Copy SourceFiles="%(ExeFiles.AppConfigTpl)"
        DestinationFiles="%(ExeFiles.FullPath).config.tpl"
        Condition="Exists('%(ExeFiles.AppConfigTpl)') />
  <!-- If needed you could raise an error like this -->
  <Error Text="oops no tpl" Condition="!Exists('%(ExeFiles.AppConfigTpl)')" />
</Target>
Другие вопросы по тегам