Мне пришлось написать собственное задание, чтобы сделать это:
Вот как это работает
<ItemGroup>
<ItemsToChange Include="@(SolutionToBuild)">
<Properties>ChangedValue</Properties>
</ItemsToChange>
<MetaDataToChange Include="Properties"/>
</ItemGroup>
<UpdateMetadata SourceList="@(SolutionToBuild)" ItemsToModify="@(ItemsToChange)" MetadataToModify="@(MetaDataToChange)">
<Output TaskParameter="NewList" ItemName="SolutionToBuildTemp" />
</UpdateMetadata>
<ItemGroup>
<SolutionToBuild Remove="@(SolutionToBuild)"/>
<SolutionToBuild Include ="@(SolutionToBuildTemp)"/>
</ItemGroup>
Заполняет новый элемент с именем SolutionToBuildTemp измененным значением. Затем я удаляю все в элементе SolutionToBuild и заполняю его с помощью элемента SolutionToBuildTemp.
Вот код для задания, если кому-то интересно (я тоже отправил его в MSBuildExtenstionPack).
// By Stephen Schaff (Vaccano).
// Free to use for your code. Need my Permission to Sell it.
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace UpdateMetadata
{
///<summary>
/// Used to update the metadata in a ItemGroup (Note: Requires an MSBuild Call After using this task to complete the update. See Usage.)
/// Usage:
/// <?xml version="1.0" encoding="utf-8"?>
///<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Testing" ToolsVersion="3.5">
///
/// <!-- Do not edit this -->
/// <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets" />
/// <UsingTask AssemblyFile="C:\Base\Junk\UpdateMetadata\UpdateMetadata\bin\Debug\UpdateMetadata.dll" TaskName="UpdateMetadata"/>
///
///
/// <!--Re-setup the solutions to build definition-->
/// <ItemGroup>
/// <SolutionToBuild Include="$(BuildProjectFolderPath)\ChangeThisOne.sln">
/// <Properties>Change</Properties>
/// </SolutionToBuild>
/// <SolutionToBuild Include="$(BuildProjectFolderPath)\ChangeThisToo.sln">
/// <Properties>Change</Properties>
/// </SolutionToBuild>
/// <SolutionToBuild Include="$(BuildProjectFolderPath)\DontChangeThisOne.sln">
/// <Properties>Don'tChange</Properties>
/// </SolutionToBuild>
/// </ItemGroup>
///
/// <Target Name="Testing">
/// <Message Text="Before = %(SolutionToBuild.Identity) %(SolutionToBuild.Properties)" />
///
/// <ItemGroup>
/// <ItemsToChange Include="@(SolutionToBuild)">
/// <Properties>ChangedValue</Properties>
/// </ItemsToChange>
///
/// <ItemsToChange Remove="%(ItemsToChange.rootdir)%(ItemsToChange.directory)DontChangeThisOne%(ItemsToChange.extension)"/>
/// </ItemGroup>
///
/// <ItemGroup>
/// <MetaDataToChange Include="Properties"/>
/// </ItemGroup>
///
/// <UpdateMetadata SourceList="@(SolutionToBuild)" ItemsToModify="@(ItemsToChange)" MetadataToModify="@(MetaDataToChange)">
/// <Output TaskParameter="NewList" ItemName="SolutionToBuildTemp" />
/// </UpdateMetadata>
///
/// <ItemGroup>
/// <SolutionToBuild Remove="@(SolutionToBuild)"/>
/// <SolutionToBuild Include ="@(SolutionToBuildTemp)"/>
/// </ItemGroup>
///
/// <Message Text="After = %(SolutionToBuild.Identity) %(SolutionToBuild.Properties)"/>
/// </Target>
///</Project>
///</summary>
public class UpdateMetadata : Task
{
///<summary>
/// The list to modify.
///</summary>
[Required]
public ITaskItem[] SourceList { get; set; }
///<summary>
/// Items in <see cref="SourceList"/> to change the Metadata for.
/// It should have the valid metadata set.
///</summary>
[Required]
public ITaskItem[] ItemsToModify { get; set; }
///<summary>
/// List of metadata to modify. This is an item group, but any metadata in it is ignored.
///</summary>
public ITaskItem[] MetadataToModify { get; set; }
///<summary>
/// If true then info about the update is output
///</summary>
public Boolean OutputMessages { get; set; }
///<summary>
/// Changed List. If you call the following it can replace the <see cref="SourceList"/>:
///</summary>
[Output]
public ITaskItem[] NewList { get; set; }
///<summary>
/// Runs the task to output the updated version of the property
///</summary>
///<returns></returns>
public override bool Execute()
{
// If we got empty params then we are done.
if ((SourceList == null) || (ItemsToModify == null) || (MetadataToModify == null))
{
Log.LogMessage("One of the inputs to ModifyMetadata is Null!!!", null);
return false;
}
if (OutputMessages)
Log.LogMessage(MessageImportance.Low, "Beginning Metadata Changeover", null);
int sourceIndex = 0;
foreach (ITaskItem sourceItem in SourceList)
{
// Fill the new list with the source one
NewList = SourceList;
foreach (ITaskItem itemToModify in ItemsToModify)
{
// See if this is a match. If it is then change the metadat in the new list
if (sourceItem.ToString() == itemToModify.ToString())
{
foreach (ITaskItem metadataToModify in MetadataToModify)
{
try
{
if (OutputMessages)
Log.LogMessage(MessageImportance.Low, "Changing {0}.{1}",
NewList[sourceIndex].ToString(), metadataToModify.ToString());
// Try to change the metadata in the new list.
NewList[sourceIndex].SetMetadata(metadataToModify.ToString(),
itemToModify.GetMetadata(metadataToModify.ToString()));
}
catch (System.ArgumentException exception)
{
// We got some bad metadata (like a ":" or something).
Log.LogErrorFromException(exception);
return false;
}
}
}
}
sourceIndex += 1;
}
return true;
}
}
}
Надеюсь, это кому-нибудь пригодится, но код, очевидно, «Используйте на свой страх и риск».
Vaccano