В MSBuild я могу использовать функцию String.Replace для элемента MetaData?
В MSBuild v4 можно использовать функции (например, string.replace
) на свойства. Но как я могу использовать функции на метаданных?
Я хотел бы использовать string.replace
функция как ниже:
<Target Name="Build">
<Message Text="@(Files->'%(Filename).Replace(".config","")')" />
</Target>
К сожалению, это приводит к (не совсем то, что я хотел): log4net.Replace (". Config","");ajaxPro.Replace(". Config","");appSettings.Replace(". Config","");cachingConfiguration20.Replace(" Конфигурация " "");. cmsSiteConfiguration.Replace("");dataProductsGraphConfiguration.Replace(" "конфигурации." Конфигурация " ""); ajaxPro.Replace. (". конфигурации", ""); appSettings.Replace ("конфигурация", ""); cachingConfiguration20.Replace ("конфигурация.","");cmsSiteConfiguratio
Какие-нибудь мысли?
6 ответов
Вы можете сделать это с небольшой хитростью:
$([System.String]::Copy('%(Filename)').Replace('config',''))
По сути, мы вызываем статический метод "Копировать" для создания новой строки (по какой-то причине он не нравится, если вы просто попытаетесь $('%(Filename)'.Replace('.config',''))
), затем вызовите функцию замены в строке.
Полный текст должен выглядеть так:
<Target Name="Build">
<Message Text="@(Files->'$([System.String]::Copy("%(Filename)").Replace(".config",""))')" />
</Target>
Изменить: MSBuild 12.0, кажется, сломал вышеупомянутый метод. В качестве альтернативы мы можем добавить новую запись метаданных ко всем существующим Files
Предметы. Мы выполняем замену при определении элемента метаданных, а затем получаем доступ к измененному значению, как и любой другой элемент метаданных.
например
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Files Include="Alice.jpg"/>
<Files Include="Bob.not-config.gif"/>
<Files Include="Charlie.config.txt"/>
</ItemGroup>
<Target Name="Build">
<ItemGroup>
<!--
Modify all existing 'Files' items so that they contain an entry where we have done our replace.
Note: This needs to be done WITHIN the '<Target>' (it's a requirment for modifying existing items like this
-->
<Files>
<FilenameWithoutConfig>$([System.String]::Copy('%(Filename)').Replace('.config', ''))</FilenameWithoutConfig>
</Files>
</ItemGroup>
<Message Text="@(Files->'%(FilenameWithoutConfig)')" Importance="high" />
</Target>
</Project>
Результат:
D:\temp>"c:\Program Files (x86)\MSBuild\12.0\Bin\MSBuild.exe" /nologo test.xml
Build started 2015/02/11 11:19:10 AM.
Project "D:\temp\test.xml" on node 1 (default targets).
Build:
Alice;Bob.not-config;Charlie
Done Building Project "D:\temp\test.xml" (default targets).
Мне нужно было сделать нечто подобное, у меня сработало следующее.
<Target Name="Build">
<Message Text="@(Files->'%(Filename)'->Replace('.config', ''))" />
</Target>
Эти функции работают только в свойствах (насколько я знаю). Итак, создайте цель, которая будет выполнять операцию броска:
<Target Name="Build"
DependsOnTargets="ProcessFile" />
<Target Name="ProcessFile"
Outputs="%(Files.Identity)">
<PropertyGroup>
<OriginalFileName>%(Files.Filename)</OriginalFileName>
<ModifiedFileName>$(OriginalFileName.Replace(".config",""))</ModifiedFileName>
</PropertyGroup>
<Message Text="$(ModifiedFileName)" Importance="High"/>
</Target>
Вы действительно нуждаетесь в своем примере в таком задании? Я имею в виду, что существуют метаданные общеизвестного элемента MSBuild
РЕДАКТИРОВАТЬ: я должен указать, что эта задача обрабатывает все элементы в @(файлы).
Я не думаю, что вы можете использовать функции напрямую с группами элементов и метаданными (это было бы легко), однако вы можете использовать пакетирование:
Взять идеи из этого поста: массив-итерация
Я пытался урезать группу элементов для отправки в инструмент командной строки (мне нужно было потерять.server за пределами имени файла)
<Target Name="ProcessFile" DependsOnTargets="FullPaths">
<ItemGroup>
<Environments Include="$(TemplateFolder)\$(Branch)\*.server.xml"/>
</ItemGroup>
<MSBuild Projects=".\Configure.msbuild"
Properties="CurrentXmlFile=%(Environments.Filename)"
Targets="Configure"/>
</Target>
<Target Name="Configure" DependsOnTargets="FullPaths">
<PropertyGroup>
<Trimmed>$(CurrentXmlFile.Replace('.server',''))</Trimmed>
</PropertyGroup>
<Message Text="Trimmed: $(Trimmed)"/>
<Exec Command="ConfigCmd $(Trimmed)"/>
</Target>
Для MSBuild 12.0 вот альтернатива.
<Target Name="Build">
<Message Text="$([System.String]::Copy("%(Files.Filename)").Replace(".config",""))" />
</Target>
У меня та же проблема (за исключением MakeRelative), поэтому я перешел к другому решению: использовать старый добрый CreateItem, который принимает строку и преобразует ее в Item:)
<ItemGroup>
<_ToUploadFTP Include="$(PublishDir)**\*.*"></_ToUploadFTP>
</ItemGroup>
<CreateItem Include="$([MSBuild]::MakeRelative('c:\$(PublishDir)','c:\%(relativedir)%(filename)%(_ToUploadFTP.extension)'))">
<Output ItemName="_ToUploadFTPRelative" TaskParameter="Include"/>
</CreateItem>
<FtpUpload Username="$(UserName)"
Password="$(UserPassword)"
RemoteUri="$(FtpHost)"
LocalFiles="@(_ToUploadFTP)"
RemoteFiles="@(_ToUploadFTPRelative->'$(FtpSitePath)/%(relativedir)%(filename)%(extension)')"
UsePassive="$(FtpPassiveMode)" ></FtpUpload>