7

我的 MSBuild 文件中有一个项目列表:

<ItemGroup>
    <SubProject Include="**\*.csproj" />
</ItemGroup>

现在,我想在每个项目上TargetPath为每个项目设置一个元数据属性。

我已经知道如何提取每个项目的目标路径,并将其放在单独的项目列表中:

<Target Name="ExtractTargetPaths">
    <MSBuild Projects="%(SubProject.Identity)" Targets="GetTargetPath">
        <Output TaskParameter="TargetOutputs" ItemName="SubProjectTargetPath" />
    </MSBuild>
</Target>

但是,我希望能够将“SubProjectTargetPath”作为项目的元数据访问,SubProject而不是拥有单独的项目列表。

也就是说,而不是这样写:

<SomeTask Parameter="%(SubProjectTargetPath.Identity)" />

我将能够写出类似的东西:

<SomeTask Parameter="%(SubProject.TargetPath)" />
4

1 回答 1

7

好的,我找到了一种解决方案,即使用具有临时属性的目标批处理:

<ItemGroup>
    <SubProject Include="**\*.csproj" />
</ItemGroup>

<Target Name="UpdateSubProjectMetadata" Outputs="%(SubProject.Identity)">
    <!-- Retrieves the Target DLL path and puts it in the temporary property "_TempTargetPath" -->
    <MSBuild Projects="%(SubProject.Identity)" Targets="GetTargetPath">
        <Output TaskParameter="TargetOutputs" PropertyName="_TempTargetPath" />
    </MSBuild>

    <!-- Set the metadata item for TestProject to the value of the temporary property -->
    <ItemGroup>
        <SubProject Condition="'%(SubProject.Identity)' == '%(Identity)'" >
            <TargetPath>$(_TempTargetPath)</TargetPath>
        </SubProject>
    </ItemGroup>
    <!-- Clear the temporary property -->
    <PropertyGroup>
        <_TempTargetPath></_TempTargetPath>
    </PropertyGroup>
</Target>

一旦该目标运行,TargetPath 就可用于每个元数据项。

实施说明:以上代码仅针对 MSBuild 4.0 进行了测试——我认为它在 MSBuild 3.5 上的工作原理与以前版本一样,并且以前版本的用户将使用<CreateItem>and<CreateProperty>任务而不是放置<PropertyGroup>and <ItemGroup>

于 2012-07-04T15:02:55.723 回答