2010-09-11 14 views
13

MSBuild'in Kopyalama görevini kullanarak yinelenen bir klasörü çoklu hedef klasörlerine kopyalamaya çalışıyorum. Bana iyi bir başlangıç ​​verdi şu soruyu gördüm, ama bir şey eksik gerekir:MSBuild Kopyalama Görevini Birden Çok Hedef Klasörüne Kopyalamak için nasıl kullanabilirim?

Msbuild copy to several locations based on list of destination parameter?

benim yapı dosyasından bir pasajı aşağıdaki gibidir:

<ItemGroup> 
    <DeployPath Include="\\server1\path" /> 
    <DeployPath Include="\\server2\path" /> 
</Item Group> 

<Target Name="Deploy"> 
    <Message Text="%(DeployPath.Identity)" /> 
    <Copy SourceFiles="@(ItemsToCopy)" DestinationFolder="%(DeployPath.Identity)\%(RecursiveDir)" /> 
</Target> 

Bunu çalıştırmak Ben beklediğiniz gibi "Mesaj" görevi, 2 satırları dışarı tükürür:

\\server1\path 
\\server2\path 

sorun, "kopyala" görevi sadece bir kez çalıştırmak için görünür ve köküne kopyalar dosyaları olduğunu Geçerli sabit disk ve belirtilen ağ yolları: C:\file1.txt yerine \\server1\path\file1.txt

için

kopyalar Ben MSBuild için oldukça yeni, bu yüzden burada oldukça basit bir şey eksik gibi hissediyorum.

Herhangi bir yardım büyük memnuniyetle karşılanacaktır.

cevap

22

Burada neyle uğraşıyorsunuz toplu iş olarak bilinir. Gruplama hakkında biraz blog yazdım. Bloglarımı http://sedotech.com/Resources#Batching adresinde bulabilirsiniz. Batching, MSBuild'de gerçekten bir şey yapmadan bir döngü yapmanın bir yoludur. Grupları ortak bir meta veri değeriyle değerlere ayırabilirsiniz. Meta veriler Identity, FullPath, Filename vb. Değerler olabilir. Kendi meta verilerinizi bile yapabilirsiniz. Her halükarda, 1'den fazla değerde gruplandırdığınızda, birbirlerinden bağımsız olarak gruplanırlar. Oluşturduğum örneğe bir bakın. Hedefin yürütülmesinin sonucu, komut dosyasından sonra gösterilir.

<Project ToolsVersion="4.0" DefaultTargets="Demo" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 

    <ItemGroup> 
    <ItemsToCopy Include="src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt"/> 
    </ItemGroup> 

    <ItemGroup> 
    <DeployPath Include="C:\temp\path01\" /> 
    <DeployPath Include="C:\temp\path02\" /> 
    </ItemGroup> 

    <!-- 
    Target batching is happening here because there is a 
    %() expression inside the Outputs attribute. So that 
    means that this target will be repeated once per 
    uinque batch of %(DeployPath.Identity). Identity is 
    the value that is passed in the Incude= attribute. 
    Since we know there are two values we know that 
    this target will be executed twice, and on each 
    pass the DeployPath item will only look to contain 
    a single value. If there were duplicates then the list 
    could contain more than 1 value. 
    --> 
    <Target Name="Demo" Outputs="%(DeployPath.Identity)"> 
    <Message Text="DeployPath.Identity: %(DeployPath.Identity)" /> 

    <Message Text="======================================" Importance="high"/> 
    <Message Text="ItemsToCopy1: @(ItemsToCopy)|| DeployPath.Identity: %(DeployPath.Identity)" /> 
    <Message Text="======================================" Importance="high"/> 
    <!-- 
     In the next emample you are batching on both the DeployPath item list as well as 
     the ItemsToCopy item. When two batched items are in the same expression they are 
     matched individually, so you ge a value for DeployPath metadata but not ItemsToCopy 
     metadata. That is why your copy only copied to one location. 
    --> 
    <Message Text="ItemsToCopy2: @(ItemsToCopy)|| DeployPath.Identity-RecursiveDir: %(DeployPath.Identity)\%(RecursiveDir)" /> 
    <Message Text="======================================" Importance="high"/> 
    <!-- 
     In this example I create a property and assign it the value of 
     %(DeployPath.Identity). We know there will only be one such 
     value. Because there should only be one value with Identity 
     when this target is executed so it is safe to 
     convert item to property 

     Because we are not batching on both items we will get the values for both vaules 
     to be correct becuase the target is repeated for the other 
     DeployPath values. 
    --> 
    <PropertyGroup> 
     <_DeployPathIdentity>%(DeployPath.Identity)</_DeployPathIdentity> 
    </PropertyGroup> 
    <Message Text="ItemsToCopy3: @(ItemsToCopy)|| _DeployPathIdentity-RecursiveDir: $(_DeployPathIdentity)\%(RecursiveDir)" /> 

    <!-- 
     I've always preferred to use DestinationFiles so my sample 
     below uses that. But you could change the target to use 
     DestinationFolder instead. 
    --> 
    <Copy SourceFiles="@(ItemsToCopy)" 
      DestinationFiles="@(ItemsToCopy->'$(_DeployPathIdentity)%(RecursiveDir)%(Filename)%(Extension)')" /> 
    </Target> 

</Project> 

Çıktı

bulmacanın en önemli eksik parça her zaman sadece bir öğe için hedef idam ettirmekle onsuz Target elemana Outputs nitelik olarak görünmektedir
Build started 9/10/2010 9:31:28 PM. 
Project "I:\Development\My Code\Community\MSBuild\CopyFiles01.proj" on node 1 (default targets). 
Demo: 
    DeployPath.Identity: C:\temp\path01\ 
    ====================================== 
    ItemsToCopy1: src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt|| DeployPath.I 
    dentity: C:\temp\path01\ 
    ====================================== 
    ItemsToCopy2: || DeployPath.Identity-RecursiveDir: C:\temp\path01\\ 
    ItemsToCopy2: src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt|| DeployPath.I 
    dentity-RecursiveDir: \ 
    ====================================== 
    ItemsToCopy3: src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt|| _DeployPathI 
    dentity-RecursiveDir: C:\temp\path01\\ 
    Creating directory "C:\temp\path01". 
    Copying file from "src\0001.txt" to "C:\temp\path01\0001.txt". 
    Copying file from "src\0002.txt" to "C:\temp\path01\0002.txt". 
    Copying file from "src\sub\sub-0001.txt" to "C:\temp\path01\sub-0001.txt". 
    Copying file from "src\sub\sub-0002.txt" to "C:\temp\path01\sub-0002.txt". 
Demo: 
    DeployPath.Identity: C:\temp\path02\ 
    ====================================== 
    ItemsToCopy1: src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt|| DeployPath.I 
    dentity: C:\temp\path02\ 
    ====================================== 
    ItemsToCopy2: || DeployPath.Identity-RecursiveDir: C:\temp\path02\\ 
    ItemsToCopy2: src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt|| DeployPath.I 
    dentity-RecursiveDir: \ 
    ====================================== 
    ItemsToCopy3: src\0001.txt;src\0002.txt;src\sub\sub-0001.txt;src\sub\sub-0002.txt|| _DeployPathI 
    dentity-RecursiveDir: C:\temp\path02\\ 
    Creating directory "C:\temp\path02". 
    Copying file from "src\0001.txt" to "C:\temp\path02\0001.txt". 
    Copying file from "src\0002.txt" to "C:\temp\path02\0002.txt". 
    Copying file from "src\sub\sub-0001.txt" to "C:\temp\path02\sub-0001.txt". 
    Copying file from "src\sub\sub-0002.txt" to "C:\temp\path02\sub-0002.txt". 
Done Building Project "I:\Development\My Code\Community\MSBuild\CopyFiles01.proj" (default targets 
). 


Build succeeded. 
+0

Mükemmel açıklama ve örnek. Teşekkürler! – WayneC

+0

Kendimi tekmeleyebilirim - bu çözümü açık bir saat önce açıklamıştı, ancak çalışmak için birden fazla destinasyona gitmek için uğraşmaya devam ettiler - 3. yaklaşım bunu yaptı! – Oliver

3

tüm liste Diğer parça, yolda tanımlamanız gereken yeni mülktür.

sorununuza çözüm şu şekilde görünecektir:

<ItemGroup> 
    <DeployPath Include="\\server1\path" /> 
    <DeployPath Include="\\server2\path" /> 
</Item Group> 

<Target Name="Deploy" Outputs="%(DeployPath.Identity)"> 
    <PropertyGroup> 
     <Destination>%(DeployPath.Identity)</Destination> 
    </PropertyGroup> 
    <Message Text="Processing: '$(Destination)" /> 
    <Copy SourceFiles="@(ItemsToCopy)" 
      DestinationFolder="%(DeployPath.Identity)\%(RecursiveDir)" /> 
</Target> 
İlgili konular