2008-11-07 29 views
13

當我在MSBUILD中的文件上執行ReadLinesFromFile並再次輸出該文件時,我在一行上獲取所有文本。所有的回車和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將一次一行地提取數據並去除回車符。

有沒有辦法讓他們回來? 所以我的電子郵件看起來都很好格式化?

感謝

回答

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

太棒了!對於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" 
         /> 

這將複製文件合併就是這樣。

相關問題