Подтвердить что ты не робот

В MSBuild я могу использовать функцию String.Replace в элементе MetaData?

В MSBuild v4 можно использовать функции (например, string.replace) в свойствах. Но как я могу использовать функции в метаданных?

Я хотел бы использовать функцию string.replace, как показано ниже:

<Target Name="Build">
        <Message Text="@(Files->'%(Filename).Replace(&quot;.config&quot;,&quot;&quot;)')" />
</Target>   

К сожалению, это означает, что (не совсем то, что я собирался):    log4net.Replace( "конфигурационный", "); ajaxPro.Replace(" конфигурация "," ".); appSettings.Replace(" конфигурация. "," "); cachingConfiguration20.Replace(" конфигурация "," ". ); cmsSiteConfiguration.Replace(" конфигурация "," "); dataProductsGraphConfiguration.Replace(" конфигурация "," ");. ajaxPro.Replace(" конфигурация. "," "); appSettings.Replace(" конфигурация ",." "); cachingConfiguration20.Replace(" конфигурация "," ");. cmsSiteConfiguratio

Любые мысли?

4b9b3361

Ответ 1

Вы можете сделать это с небольшим количеством обмана:

$([System.String]::Copy('%(Filename)').Replace('config',''))

В принципе, мы вызываем статический метод "Копировать" для создания новой строки (по какой-то причине это не нравится, если вы просто пытаетесь выполнить $('%(Filename)'.Replace('.config',''))), а затем вызовите функцию replace в строке.

Полный текст должен выглядеть следующим образом:

<Target Name="Build">
        <Message Text="@(Files->'$([System.String]::Copy(&quot;%(Filename)&quot;).Replace(&quot;.config&quot;,&quot;&quot;))')" />
</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 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).

Ответ 2

Эти функции работают только в свойствах (как я знаю). Итак, создайте цель, которая будет выполнять пакетное дозирование операции:

<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 Хорошо известные метаданные элементов

EDIT: Я должен указать, что эта задача обрабатывает все элементы в @(файлы).

Ответ 3

Мне нужно было сделать что-то подобное, следующее работало для меня.

<Target Name="Build">
  <Message Text="@(Files->'%(Filename)'->Replace('.config', ''))" />
</Target>

Ответ 4

Для MSBuild 12.0, здесь альтернатива.

<Target Name="Build">
    <Message Text="$([System.String]::Copy(&quot;%(Files.Filename)&quot;).Replace(&quot;.config&quot;,&quot;&quot;))" />
</Target>

Ответ 5

Я не думаю, что вы можете использовать функции напрямую с группами элементов и метаданными (это было бы легко) Однако вы можете использовать пакетную обработку:

Принимая идеи из этого поста: array-iteration

Я пытался обрезать группу элементов для отправки в инструмент командной строки (мне нужно было потерять сервер с именем файла)

<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>

Ответ 6

У вас такая же проблема (кроме 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>