2008-11-05 101 views
7

我需要編寫腳本。我使用MSBUILD是因爲它與VS.net集成。我正在嘗試從構建環境中將一些文件複製到部署文件夾。我正在使用MSBuild的複製任務。但不是像我所期望的那樣複製目錄樹。它將所有內容複製到一個文件夾中。我將目錄樹中的所有文件重複放到一個文件夾中。我需要它將文件夾和目錄樹複製到目標文件夾中。有什麼我失蹤?MSBuild爲什麼不像我期望的那樣複製

這裏是我的構建腳本的初步認識部分:

<PropertyGroup> 
    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion> 
    <Source>outputfolder</Source> 
    <DestEnv>x</DestEnv> 
    <DeployPath>\\networkpath\$(DestEnv)</DeployPath> 
</PropertyGroup> 
<ItemGroup> 
    <TargetDir Include="$(DeployPath)\**\*" Exclude="**\web.config"></TargetDir> 
    <SourceDir Include="$(Source)\**\*" /> 
</ItemGroup>  
<Target Name="Clean" > 
    <!-- clean detail ... --> 
</Target> 
<Target Name="migrate" DependsOnTargets="Clean"> 
    <Copy DestinationFolder="$(DeployPath)" SourceFiles="@(SourceDir)" /> 
</Target> 

回答

4

我發現例如在一個例子中MSDN我不明白,但會在計算器離開這裏的一個例子我的同胞travlers 。下面是遷移目標從上面的固定版本:

<Target Name="migrate" DependsOnTargets="Clean"> 
    <Copy DestinationFiles="@(SourceDir->'$(DeployPath)\%(RecursiveDir)%(Filename)%(Extension)')" SourceFiles="@(SourceDir)" /> 
</Target> 

如果有人真的理解這個例子請解釋。祝你好運!

12

當您爲複製任務指定DestinationFolder時,它將從SourceFiles集合中獲取所有項目並將它們複製到DestinationFolder。這是預料之中的,因爲Copy任務無法確定每個項目的路徑的哪部分需要用DestinationFolder替換以保持樹結構。例如,如果您的SourceDir集合是這樣定義的:

<ItemGroup> 
    <SourceDir Include="$(Source)\**\*" /> 
    <SourceDir Include="E:\ExternalDependencies\**\*" /> 
    <SourceDir Include="\\sharedlibraries\gdiplus\*.h" /> 
</ItemGroup> 

您認爲目標文件夾樹的外觀如何?

要保存樹,您需要進行標識轉換併爲SourceFiles集合中的每個項目生成一個目標項目。這裏有一個例子:

<Copy SourceFiles="@(Compile)" DestinationFiles="@(Compile->'$(DropPath)%(Identity)')" /> 

副本任務將採取每個項目在SourceFiles集合,並通過在源項目規範與$(DropPath)前更換**部分轉換其路徑。

有人可能會爭辯說,DestinationFolder屬性應該已被寫入作爲快捷方式如下改造:

<Copy SourceFiles="@(Compile)" DestinationFiles="@(Compile->'$(DestinationFolder)%(Identity)')" /> 

唉,這將防止深複製到平面文件夾的場景,你正試圖避免的,但其他人可能會在構建過程中使用。

5

很簡單的例子,複製目錄內容和結構遞歸:

<Copy SourceFiles="@(Compile)" DestinationFolder="c:\foocopy\%(Compile.RecursiveDir)"></Copy> 

@(編譯)是要複製所有文件的的ItemGroup。可能是這樣的:

<ItemGroup> 
     <Compile Include=".\**\*.dll" /> 
    </ItemGroup> 

複製任務將複製所有文件到c:\ foocopy就像xcopy。

+0

<複製SourceFiles = 「$(SourceViewsLocation)」 DestinationFolder = 「$(RepositoryLocation)\%(RecursiveDir)」> 給出了錯誤:MSBUILD:錯誤MSB4095:該項目的元數據%(RecursiveDir)沒有被引用項目名。使用%(itemname.RecursiveDir)指定項目名稱。 – 2009-05-29 08:09:26

13

只是一個寶石,我們發現當我們周圍複製調試MSBuild的問題:

http://blog.scrappydog.com/2008/06/subtle-msbuild-bug-feature.html

ItemGroups的目標之前解析,使創建新文件的任何目標(例如編譯!)在沿着腳本進一步引用ItemGroup時不會被拾取。

埃裏克·博文還介紹了一種繞過這個「功能」,該CreateItem任務:

<Target Name="Copy" > 
    <CreateItem Include="..\Source\**\bin\**\*.exe" 
     Exclude="..\Source\**\bin\**\*.vshost.exe"> 
     <Output TaskParameter="Include" ItemName="CompileOutput" /> 
    </CreateItem> 
    <Copy SourceFiles="@(CompileOutput)" 
     DestinationFolder="$(OutputDirectory)"></Copy> 
</Target> 

許多榮譽給他!

相關問題