Msbuild 复制项目';用于批处理的元数据

Msbuild 复制项目';用于批处理的元数据,msbuild,Msbuild,这是对的扩展。 假设我正在从其他项的元数据创建项: <ItemGroup> <A> <files>f1;f2;f3;...</files> <x>...</x> <y>...</y> <z>...</z> ... </A> <B Include="%(A.f

这是对的扩展。
假设我正在从其他项的元数据创建项:

<ItemGroup>
    <A>
        <files>f1;f2;f3;...</files>
        <x>...</x>
        <y>...</y>
        <z>...</z>
        ...
    </A>
    <B Include="%(A.files)">
        <x>%(A.x)</x>
        <y>%(A.y)</y>
        <z>%(A.z)</z>
        ...
    </B>
</ItemGroup>

f1;f2;f3;。。。
...
...
...
...
%(A.x)
%(A.y)
%(A.z)
...
%(A.files)
是由
分隔的文件列表,这样对于每个A项,我将创建多个B项(每个文件一个)。
但在处理
B
项目时,我经常需要原始的
A
项目元数据。在本例中,我手动将每个元数据从
A
复制到
B


有没有一种方法可以将a的所有元数据复制到B,而无需明确指定其中的每一个元数据?

我不确定是否得到了您需要的元数据,但您可以将a的所有元数据复制到B,如下所示:



它应该将所有metedata从A复制到B。

我不确定是否得到了您需要的,但您可以将所有A metedata复制到B,如下所示:



它应该将所有metedata从A复制到B。

据我所知,MSBuild仅在输入和输出项列表之间存在一对一映射时复制元数据。在您的情况下,您从一个项目开始,然后扩展到多个项目。为了解决这个问题,我建议使用项目批处理:

<?xml version="1.0" encoding="iso-8859-1"?>
<Project
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
    ToolsVersion="4.0"
    DefaultTargets="Print">

    <ItemGroup>
        <A Include="A1">
            <files>test.htm;test_sol1.htm</files>
            <x>a1</x>
            <y>b1</y>
            <z>c1</z>
        </A>
        <A Include="A2">
            <files>test.proj</files>
            <x>a2</x>
            <y>b2</y>
            <z>c2</z>
        </A>
    </ItemGroup>

    <Target Name="ExpandA">
        <ItemGroup>
            <ExpandedA Include="%(A.files)">
                <Original>%(Identity)</Original>
            </ExpandedA>
        </ItemGroup>
    </Target>

    <Target
        Name="CopyMetadata"
        Outputs="%(ExpandedA.Identity)"
        DependsOnTargets="ExpandA">

        <PropertyGroup>
            <ExpandedAIdentity>%(ExpandedA.Identity)</ExpandedAIdentity>
            <ExpandedAOriginal>%(ExpandedA.Original)</ExpandedAOriginal>
        </PropertyGroup>
        <ItemGroup>
            <ExpandedAMetadata Include="@(A)" Condition=" '%(Identity)' == '$(ExpandedAOriginal)' ">
                <Expanded>$(ExpandedAIdentity)</Expanded>
            </ExpandedAMetadata>
        </ItemGroup>
    </Target>

    <Target Name="Print" DependsOnTargets="CopyMetadata">
        <ItemGroup>
            <B Include="@(ExpandedAMetadata->'%(Expanded)')" />
        </ItemGroup>

        <!--Use commas to illustrate that "files" has been expanded-->
        <Message Text="A: %(A.files)" />
        <Message Text="ExpandedA: @(ExpandedA, ',')" />
        <Message Text="ExpandedAMetadata: @(ExpandedAMetadata, ',')" />
        <Message Text="B: @(B->'%(Identity) x:%(x) y:%(y) z:%(z)', ',')" />
    </Target>
</Project>

ExpandedA
与您原来问题中的
B
类似;它是
A
的扩展版本,但没有任何元数据。然后,我为
ExpandedA
中的每个项目运行一次
copymetada
目标(多亏了项目批处理)。每次运行时,原始
A
项连同其所有元数据一起复制到
expandedatadata
项组。
原始
元数据用于确保正确的
A
项与每个文件关联。最后,在
Print
目标中,使用项转换构造
B
,以便将
ExpandedAMetadata
中的所有元数据也复制过来。

据我所知,当输入和输出项列表之间存在一对一映射时,MSBuild仅复制元数据。在您的情况下,您从一个项目开始,然后扩展到多个项目。为了解决这个问题,我建议使用项目批处理:

<?xml version="1.0" encoding="iso-8859-1"?>
<Project
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
    ToolsVersion="4.0"
    DefaultTargets="Print">

    <ItemGroup>
        <A Include="A1">
            <files>test.htm;test_sol1.htm</files>
            <x>a1</x>
            <y>b1</y>
            <z>c1</z>
        </A>
        <A Include="A2">
            <files>test.proj</files>
            <x>a2</x>
            <y>b2</y>
            <z>c2</z>
        </A>
    </ItemGroup>

    <Target Name="ExpandA">
        <ItemGroup>
            <ExpandedA Include="%(A.files)">
                <Original>%(Identity)</Original>
            </ExpandedA>
        </ItemGroup>
    </Target>

    <Target
        Name="CopyMetadata"
        Outputs="%(ExpandedA.Identity)"
        DependsOnTargets="ExpandA">

        <PropertyGroup>
            <ExpandedAIdentity>%(ExpandedA.Identity)</ExpandedAIdentity>
            <ExpandedAOriginal>%(ExpandedA.Original)</ExpandedAOriginal>
        </PropertyGroup>
        <ItemGroup>
            <ExpandedAMetadata Include="@(A)" Condition=" '%(Identity)' == '$(ExpandedAOriginal)' ">
                <Expanded>$(ExpandedAIdentity)</Expanded>
            </ExpandedAMetadata>
        </ItemGroup>
    </Target>

    <Target Name="Print" DependsOnTargets="CopyMetadata">
        <ItemGroup>
            <B Include="@(ExpandedAMetadata->'%(Expanded)')" />
        </ItemGroup>

        <!--Use commas to illustrate that "files" has been expanded-->
        <Message Text="A: %(A.files)" />
        <Message Text="ExpandedA: @(ExpandedA, ',')" />
        <Message Text="ExpandedAMetadata: @(ExpandedAMetadata, ',')" />
        <Message Text="B: @(B->'%(Identity) x:%(x) y:%(y) z:%(z)', ',')" />
    </Target>
</Project>

ExpandedA
与您原来问题中的
B
类似;它是
A
的扩展版本,但没有任何元数据。然后,我为
ExpandedA
中的每个项目运行一次
copymetada
目标(多亏了项目批处理)。每次运行时,原始
A
项连同其所有元数据一起复制到
expandedatadata
项组。
原始
元数据用于确保正确的
A
项与每个文件关联。最后,在
Print
目标中,
B
是使用项转换构建的,因此
expandedatadata
中的所有元数据也会被复制过来。

有点晚,但我更喜欢这个解决方案:

<B Include="@(A->Metadata('files'))" />

有点晚了,但我更喜欢这个解决方案:

<B Include="@(A->Metadata('files'))" />

否。我需要为文件元数据中的每个文件创建一个B项,而不是像您建议的那样为每个a项创建一个B项。否。我需要为文件元数据中的每个文件创建一个B项,而不是像您建议的那样为每个a项创建一个B项。很好的解决方案,我喜欢您使用批处理的方式。但每次需要复制元数据时,我都需要编写一个额外的“CopyMetadata”目标来执行批处理。我发现自己复制元数据太频繁了,我希望会有一些“CopyMetadata”任务或类似的任务,使我能够做到这一点,而不必为每个复制操作编写另一个目标。(可能是“CopyMetadata”内联任务…)很好的解决方案,我喜欢您使用批处理的方式。但每次需要复制元数据时,我都需要编写一个额外的“CopyMetadata”目标来执行批处理。我发现自己复制元数据太频繁了,我希望会有一些“CopyMetadata”任务或类似的任务,使我能够做到这一点,而不必为每个复制操作编写另一个目标。(可能是“CopyMetadata”内联任务…)
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <ItemGroup>
        <A Include="A1">
            <files>a1_file1.htm;a1_file2.htm</files>
            <x>a1</x>
            <y>b1</y>
            <z>c1</z>
        </A>
        <A Include="A2">
            <files>a2_file.proj</files>
            <x>a2</x>
            <y>b2</y>
            <z>c2</z>
        </A>
        <B Include="@(A->Metadata('files'))" />
    </ItemGroup>

    <Target Name="Build">
        <Message Text="A: @(A->'%(Identity) x:%(x) y:%(y) z:%(z) files:%(files)', '&#x0D;&#x0A;   ')" />
        <Message Text="B: @(B->'%(Identity) x:%(x) y:%(y) z:%(z) files:%(files)', '&#x0D;&#x0A;   ')" />
    </Target>

</Project>
Build:
  A: A1 x:a1 y:b1 z:c1 files:a1_file1.htm;a1_file2.htm
     A2 x:a2 y:b2 z:c2 files:a2_file.proj
  B: a1_file1.htm x:a1 y:b1 z:c1 files:a1_file1.htm;a1_file2.htm
     a1_file2.htm x:a1 y:b1 z:c1 files:a1_file1.htm;a1_file2.htm
     a2_file.proj x:a2 y:b2 z:c2 files:a2_file.proj