Пакетное копирование списка элементов с помощью MSBuild Task RoboCopy

Есть список каталогов источника и назначения, определенных в. Мне нужна одна задача / цель для выполнения robocopy в соответствии с определенными свойствами группы элементов.

<ItemGroup>
<ItemToCopy Include="$(RootPath)\Audi">
    <WhereToCopy>$(FinalFolder)\Audi</WhereToCopy>
    <WhatToCopy>*.svc</WhatToCopy>
</ItemToCopy>
<ItemToCopy Include="$(RootPath)\Custom">
    <WhereToCopy>$(FinalFolder)\Custom</WhereToCopy>
    <WhatToCopy>*.svc</WhatToCopy>
</ItemToCopy>
<ItemToCopy Include="$(RootPath)\Audi\bin">
    <WhereToCopy>$(FinalFolder)\Audi\bin</WhereToCopy>
    <WhatToCopy>*.*</WhatToCopy>
</ItemToCopy>
<ItemToCopy Include="$(RootPath)\Custom\bin">
    <WhereToCopy>$(FinalFolder)\Custom\bin</WhereToCopy>
    <WhatToCopy>*.*</WhatToCopy>
</ItemToCopy>

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

<Target Name="CopyAll">  
   <RoboCopy  
        Source="@(ItemToCopy)"  
        Destination="%(ItemToCopy.WhereToCopy)" Files="ItemtoCopy.Whattocopy"/>  
</Target>

Кроме того, если мы видим элементы 1 и 2 (также 3 и 4), они одинаковы в том смысле, что копируют одинаковые типы файлов из их%ItemName по тому же пути с подкаталогом%ItemName. Было бы здорово, если бы мы также могли избежать этого дополнительного запаха кода. Надеюсь, что-то вроде ниже, чтобы работать:

<ItemToCopy Include="$(RootPath)\@PublishProjects">
        <WhereToCopy>$(FinalFolder)\@PublishProjects</WhereToCopy>
        <WhatToCopy>*.svc</WhatToCopy>
    </ItemToCopy>
where,
<ItemGroup>
    <PublishProjects Include="Audi" />
    <PublishProjects Include="Custom" />
  </ItemGroup>

2 ответа

Хорошо, этот ответ, который я дал, пропускает использование robocopy, которое, как я признаю, является специфической частью вашего вопроса.

@ И% все еще остаются в силе (вы не можете смешивать их использование), и именно в этом вы ошиблись в своей цели CopyAll.

<Target Name="CopyAll">  
   <RoboCopy  
        Source="@(ItemToCopy)"  
        Destination="@(ItemToCopy->'%(WhereToCopy)')" Files="@(ItemtoCopy->'%(Whattocopy)')"/>  
</Target>

Ознакомьтесь с справкой по преобразованиям, чтобы лучше понять, как их использовать. https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-transforms

Вы не можете смешивать @ и%. Оба из них указывают на операцию над группой товаров. Использование% выполняет операцию один раз для каждого элемента в группе элементов. @ выполняет операцию один раз для всей группы товаров. Обратите внимание, что не все задачи поддерживают группы элементов.

Если вы используете @, то вы используете "преобразование", которое имеет необычный синтаксис. https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-transforms

Кроме того, группы товаров предназначены для соответствия файлов для вас. Указание папок работает и относится к папке, но одна из сильных сторон msbuild - это поиск файлов для вас.

Вместо

<ItemToCopy Include="$(RootPath)\Audi">
    <WhereToCopy>$(FinalFolder)\Audi</WhereToCopy>
    <WhatToCopy>*.svc</WhatToCopy>
</ItemToCopy>

Я бы пошел с

<ItemToCopy Include="$(RootPath)Audi\*.svc">
    <TargetSubDir>Audi\</TargetSubDir>
</ItemToCopy>

Тогда ваша цель будет больше похожа

  <Target Name="CopyFiles">
    <Copy Condition="@(ItemToCopy)!=''"
          SourceFiles="@(ItemToCopy)"
          DestinationFiles="@(ItemToCopy->'$(FinalFolder)%(TargetSubDir)%(RecursiveDir)%(Filename)%(Extension)')"
          OverwriteReadOnlyFiles="true"
          SkipUnchangedFiles="true" />
  </Target>

Помните, это соглашение msbuild, что все свойства / метаданные, представляющие каталог, включают в себя завершающий слеш.

Другие вопросы по тегам