2009-08-18 11 views
16

tengo el siguiente fragmento de código msbuild:cómo invocar el mismo objetivo msbuild dos veces con diferentes parámetros dentro de sí mismo archivo de proyecto msbuild

<PropertyGroup> 
    <DirA>C:\DirA\</DirA> 
    <DirB>C:\DirB\</DirB> 
    </PropertyGroup> 

    <Target Name="CopyToDirA" 
      Condition="Exists('$(DirA)') AND '@(FilesToCopy)' != ''" 
      Inputs="@(FilesToCopy)" 
      Outputs="@(FilesToCopy -> '$(DirA)%(Filename)%(Extension)')"> 
    <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(DirA)" /> 
    </Target> 

    <Target Name="CopyToDirB" 
      Condition="Exists('$(DirB)') AND '@(FilesToCopy)' != ''" 
      Inputs="@(FilesToCopy)" 
      Outputs="@(FilesToCopy -> '$(DirB)%(Filename)%(Extension)')"> 
    <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(DirB)" /> 
    </Target> 

    <Target Name="CopyFiles" DependsOnTargets="CopyToDirA;CopyToDirB"/> 

Así invocando el objetivo CopyFiles copia los archivos pertinentes a $(DirA) y $(DirB), siempre que no estén ya allí y estén actualizados.

pero los objetivos CopyToDirACopyToDirB y aspecto idénticos excepto uno copias a $(DirA) y el otro - para $(DirB). ¿Es posible unificarlos en un solo objetivo invocado con $(DirA) y luego con $(DirB)?

Gracias.

Respuesta

14

Debería poder generar un ItemGroup que contenga los Dirs y luego% en eso.

<ItemGroup> 
    <Dirs Include="C:\DirA\;C:\DirB\"> 
</ItemGroup> 
<Target Name="CopyFiles" 
    Condition="Exists('%(Dirs)') AND '@(FilesToCopy)' != ''" 
    Inputs="@(FilesToCopy)" 
    Outputs="@(FilesToCopy -> '%(Dirs)%(Filename)%(Extension)')"> 
    <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="%(Dirs)" /> 
</Target> 

O puede hacer 2 llamadas explícitas:

<Target Name="CopyFiles"> 
    <MsBuild Projects="$(MSBuildProjectFullPath)" Targets="CopyASetOfFiles" Properties="[email protected](FilesToCopy);DestDir=$(DirA)" /> 
    <MsBuild Projects="$(MSBuildProjectFullPath)" Targets="CopyASetOfFiles" Properties="[email protected](FilesToCopy);DestDir=$(DirB)" /> 
</Target> 

<Target Name="CopyASetOfFiles" 
    Condition="Exists('$(DestDir)') AND '@(FilesToCopy)' != ''" 
    Inputs="@(FilesToCopy)" 
    Outputs="@(FilesToCopy -> '$(DestDir)%(Filename)%(Extension)')"> 
    <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(DestDir)" /> 
</Target> 

No he probado ya sea la sintaxis, pero soy relativamente más seguros de la segunda.

(La respuesta, si es que existe, es en mi libro Sayed Hashimi en mi escritorio - que tendrá que esperar hasta el primero de:

  1. Obtener el libro
  2. me aburro
  3. Sayed encuentra este post y se le ocurre una respuesta probado brillante)
+0

Hola Ruben. ¿Podrías expandir el ... en tu respuesta? No estoy tan familiarizado con los objetivos parametrizados para entender lo que quieres decir. Gracias. – mark

+0

@mark: hecho.La razón por la que no lo hice antes es doble 1. No tenía un buen editor a mano. 2. no estoy seguro de la sintaxis de la primera muestra. Espero que esto ayude. Recomiendo encarecidamente el libro Inside MSBuild –

+0

@ruben: LOL @ # 3 –

4

Sí, lo que quiere que se llama procesamiento por lotes en MSBuild. El

;%(Dirs.Identity) 

Definido en las salidas hará que esta tarea se ejecute para cada elemento en el grupo de elementos de dirs.

<?xml version="1.0" encoding="utf-8"?> 
<Project DefaultTargets="CopyFiles" 
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 
    ToolsVersion="3.5"> 

<ItemGroup> 
    <Dirs Include="C:\DirA" /> 
    <Dirs Include="C:\DirB" /> 
</ItemGroup> 

<Target Name="CopyFiles" 
    Inputs="@(FilesToCopy);@(Dirs)" 
    Outputs="@(FilesToCopy -> '%(Dirs.Identity)%(Filename)%(Extension)');%(Dirs.Identity)" > 
    <Message Text="%(Dirs.Identity)" /> 
</Target> 

</Project> 

Salidas:

Build started 8/19/2009 10:11:57 PM. 
Project "D:\temp\test.proj" on node 0 (default targets). 
    C:\DirA 
CopyFiles: 
    C:\DirB 
Done Building Project "D:\temp\test.proj" (default targets). 

cambiar la tarea de mensajes para copiar tarea con la siguiente condición y ya está:

Condition="Exists('%(Dirs.Identity)') AND '@(FilesToCopy)' != ''" 
Cuestiones relacionadas