MSBuild ReadLinesFromFile весь текст в одну строку - PullRequest
13 голосов
/ 07 ноября 2008

Когда я выполняю 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 ]

41 голосов
/ 08 ноября 2008

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

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

Таким образом, это не просто чтение всего текста из файла, это чтение отдельных элементов из файла и возврат группы элементов 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)
35 голосов
/ 18 февраля 2012

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

$([System.IO.File]::ReadAllText($FilePath))
4 голосов
/ 12 сентября 2009

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

1 голос
/ 02 февраля 2016

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

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

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

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

...