Поделиться через


Преобразования MSBuild

Преобразование — это один-к-одному преобразование одного списка элементов в другой. Преобразования позволяют проектам в Visual Studio преобразовать списки элементов. Преобразования также позволяют целевым объектам определять прямое сопоставление между входными и выходными данными.

В этой статье описываются преобразования и способы использования обработчика сборки Майкрософт (MSBuild) для более эффективного создания проектов.

Модификаторы трансформации

Преобразования не определяются произвольно. Каждое преобразование определяется как модификатор формата %(\<ItemMetaDataName>). Любые метаданные элемента можно использовать в качестве модификатора преобразования, включая известные метаданные элемента, назначенные каждому элементу при создании. Список метаданных известных элементов см. в разделе Метаданные известных элементов MSBuild.

В следующем примере список RESX-файлов преобразуется в список файлов ресурсов . Модификатор %(filename) преобразования указывает, что каждый файл ресурсов имеет то же имя файла, что и соответствующий RESX-файл :

@(RESXFile->'%(filename).resources')

Если элементы в списке @(RESXFile): Form1.resx, Form2.resx и Form3.resx, то преобразованный список содержит выходные данные Form1.resources, Form2.resources и Form3.resources.

Замечание

Разделитель по умолчанию для элементов в преобразованном списке — это точка с запятой ;. Настраиваемый разделитель можно указать таким же образом, как и разделитель для списка стандартных элементов. Чтобы разделить элементы с запятой , , используйте синтаксис @(RESXFile->'Toolset\%(filename)%(extension)', ',').

Несколько модификаторов преобразования

Выражение преобразования может содержать несколько модификаторов, которые могут быть объединены в любом порядке и могут повторяться. В следующем примере имя каталога, содержащего файлы, изменяется, но файлы сохраняют исходное имя и расширение имени файла:

@(RESXFile->'Toolset\%(filename)%(extension)')

Если элементы в списке RESXFileProject1\Form1.resx, Project1\Form2.resx и Project1\Form3.text, то преобразованный список содержит результаты Toolset\Form1.resx, Toolset\Form2.resx и Toolset\Form3.text.

Анализ зависимостей и сопоставление с целями

Преобразования гарантируют сопоставление между преобразованным списком элементов и исходным списком элементов. Если целевой объект создает выходные данные, которые преобразовывают входные данные, MSBuild может анализировать метки времени входных и выходных данных. MSBuild использует сведения для определения того, следует ли пропускать, создавать или частично перестраивать целевой объект.

В следующем примере входные данные задачи копирования преобразуются в выходные данные. Каждый файл в списке входных BuiltAssemblies элементов сопоставляется с файлом в целевой папке задачи, указанной с помощью преобразования в атрибуте Outputs . Если файл в списке BuiltAssemblies элементов изменяется, Copy task выполняется только для измененного файла и пропускает все остальные файлы.

<Target Name="CopyOutputs"
    Inputs="@(BuiltAssemblies)"
    Outputs="@(BuiltAssemblies -> '$(OutputPath)%(Filename)%(Extension)')">

    <Copy
        SourceFiles="@(BuiltAssemblies)"
        DestinationFolder="$(OutputPath)"/>

</Target>

Дополнительные сведения о анализе зависимостей и использовании преобразований см. в статье MSBuild с добавочными сборками для новых или устаревших целевых объектов.

Файл проекта с преобразованиями

В следующем примере показан файл проекта для MSBuild, использующий преобразования. В примере предполагается, что каталог c:\sub0\sub1\sub2\sub3 содержит только один XSD-файл , а рабочий каталог — c:\sub0.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <Schema Include="sub1\**\*.xsd"/>
    </ItemGroup>

    <Target Name="Messages">
        <Message Text="rootdir: @(Schema->'%(rootdir)')"/>
        <Message Text="fullpath: @(Schema->'%(fullpath)')"/>
        <Message Text="rootdir + directory + filename + extension: @(Schema->'%(rootdir)%(directory)%(filename)%(extension)')"/>
        <Message Text="identity: @(Schema->'%(identity)')"/>
        <Message Text="filename: @(Schema->'%(filename)')"/>
        <Message Text="directory: @(Schema->'%(directory)')"/>
        <Message Text="relativedir: @(Schema->'%(relativedir)')"/>
        <Message Text="extension: @(Schema->'%(extension)')"/>
    </Target>
</Project>

В примере создаются следующие выходные данные:

rootdir: C:\
fullpath: C:\sub0\sub1\sub2\sub3\myfile.xsd
rootdir + directory + filename + extension: C:\sub0\sub1\sub2\sub3\myfile.xsd
identity: sub1\sub2\sub3\myfile.xsd
filename: myfile
directory: sub0\sub1\sub2\sub3\
relativedir: sub1\sub2\sub3\
extension: .xsd