2008-11-07 8 views
13

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

<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()"" 

Я знаю, что код для ReadLinesFro mFile потянет данные в одну строку за раз и вычеркнет возврат каретки.

Есть ли способ вернуть их обратно? Итак, мой e-mail выглядит красиво отформатированным?

Благодаря

ответ

40

Проблема здесь вы используете 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)
+2

Это именно то, что я искал, спасибо, чувак! Я знал, что могу сделать это, написав пользовательскую задачу, но я бы предпочел не иметь кучу пользовательских задач о месте, если я могу сделать это с учетом синтаксиса. Еще раз спасибо !! :-) – evilhomer 2008-11-08 16:08:22

3

Вместо @ (FileContents -> '% (идентичность)', '% 0A% 0D') Я считаю, что вы можете сделать @ (FileContents, '% 0A% 0D')

33

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

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

Удивительный! Для других полезных вещей из .NET, разрешенных в MSBuild, см. Http://blogs.msdn.com/b/visualstudio/archive/2010/04/02/msbuild-property-functions.aspx – Mike 2012-12-13 15:47:34

1

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

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

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

Это будет копировать файл точно в этом есть.

 Смежные вопросы

  • Нет связанных вопросов^_^