MSBuild ReadLinesFromFile весь текст в одну строку

Когда я выполняю файл ReadLinesFromFile для файла в MSBUILD и снова вывожу этот файл, я получаю весь текст в одной строке. Все возвраты каретки и LineFeeds удаляются.

<Project DefaultTargets = "Deploy"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
<Import  Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>

<ItemGroup>
    <MyTextFile Include="$(ReleaseNotesDir)$(NewBuildNumber).txt"/>
</ItemGroup>

<Target Name="ReadReleaseNotes">
    <ReadLinesFromFile
        File="@(MyTextFile)" >
        <Output
            TaskParameter="Lines"
            ItemName="ReleaseNoteItems"/>
    </ReadLinesFromFile>
</Target>

<Target Name="MailUsers" DependsOnTargets="ReadReleaseNotes" >
    <Mail SmtpServer="$(MailServer)"
        To="$(MyEMail)"
        From="$(MyEMail)"
        Subject="Test Mail Task"
        Body="@(ReleaseNoteItems)" />
</Target>
<Target Name="Deploy">
    <CallTarget Targets="MailUsers" />
</Target>

</Project>

Я получаю текст из файла, который обычно выглядит так

- New Deployment Tool for BLAH

- Random other stuff()""

Выходит так

- New Deployment Tool for BLAH;- Random other stuff()""

Я знаю, что код ReadLinesFromFile будет извлекать данные по одной строке за раз и удалять возврат каретки.

Есть ли способ вернуть их обратно? Так что моя электронная почта выглядит красиво отформатированной?

Спасибо

4 ответа

Решение

Проблема в том, что вы используете ReadLinesFromFile задача в том виде, в котором она не была предназначена.

Задача ReadLinesFromFile
Читает список элементов из текстового файла.

Таким образом, это не просто чтение всего текста из файла, это чтение отдельных элементов из файла и возврат группы элементов ITaskItems. Всякий раз, когда вы выводите список элементов, используя @() Синтаксис вы получите отдельный список, по умолчанию которого точка с запятой. Этот пример иллюстрирует это поведение:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build"    xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

    <ItemGroup>
        <Color Include="Red" />
        <Color Include="Blue" />
        <Color Include="Green" />
</ItemGroup>

<Target Name="Build">
        <Message Text="ItemGroup Color: @(Color)" />
</Target>

</Project>

И вывод выглядит так:

  ItemGroup Color: Red;Blue;Green

Поэтому, хотя лучшим решением вашей проблемы является написание задачи MSBuild, которая считывает файл в свойство в виде строки, а не списка элементов, на самом деле это не то, что вы просили. Вы спросили, есть ли способ вернуть их, и есть ли использование MSBuild Transforms.

Преобразования используются для создания одного списка из другого, а также имеют возможность преобразования с использованием специального разделителя. Таким образом, ответ состоит в том, чтобы преобразовать ваш список, прочитанный в использовании ReadItemsFromFile в другой список с новыми строками. Вот пример, который делает именно это:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

    <ItemGroup>
        <File Include="$(MSBuildProjectDirectory)\Test.txt" />
    </ItemGroup>

    <Target Name="Build">
        <ReadLinesFromFile File="@(File)">
            <Output TaskParameter="Lines" ItemName="FileContents" />
        </ReadLinesFromFile>

        <Message Text="FileContents: @(FileContents)" />
        <Message Text="FileContents Transformed: @(FileContents->'%(Identity)', '%0a%0d')" />
    </Target>

</Project>

Test.text выглядит так:

Red
Green
Blue

И вывод выглядит так:

[C:\temp]:: msbuild test.proj
Microsoft (R) Build Engine Version 3.5.21022.8
[Microsoft .NET Framework, Version 2.0.50727.1433]
Copyright (C) Microsoft Corporation 2007. All rights reserved.

Build started 11/8/2008 8:16:59 AM.
Project "C:\temp\test.proj" on node 0 (default targets).
  FileContents: Red;Green;Blue
  FileContents Transformed: Red
Green
Blue
Done Building Project "C:\temp\test.proj" (default targets).


Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.03

Здесь происходит две вещи.

@(FileContents->'%(Identity)', '%0a%0d')   
  • Мы преобразуем список из одного типа в другой, используя те же значения (Identity) но пользовательский разделитель '%0a%0d'
  • Мы используем MSBuild Escaping, чтобы избежать перевода строки (%0a) и возврат каретки (%0d)

Если вы используете MSBuild 4.0, вы можете сделать следующее, чтобы получить содержимое файла:

$([System.IO.File]::ReadAllText($FilePath))

Вместо @(FileContents->'%(Identity)', '%0a%0d') я думаю, что вы можете сделать @(FileContents, '%0a%0d')

Вы можете использовать WriteLinesToFile в сочетании с

$([System.IO.File]::ReadAllText($(SourceFilePath))):

< WriteLinesToFile File="$(DestinationFilePath)"  Lines="$([System.IO.File]::ReadAllText($(SourceFilePath)))"
                      Overwrite="true" 
                      />

Это скопирует ваш файл именно на это.

Другие вопросы по тегам