2010-11-04 20 views
13

ejecutar esta con msbuild:¿Cómo impido que el lote de elementos ejecute un lote cuando no hay ningún elemento?

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

    <ItemGroup> 
    <Colors Include="Blue"> 
     <Shade>Dark</Shade> 
    </Colors> 
    </ItemGroup> 

    <Target Name="Main"> 
    <Message Text="Color: %(Colors.Shade) %(Colors.Identity)"/> 
    </Target> 

</Project> 

Y SALIDAS:

Color: Dark Blue 

Todo bien y bueno, pero eliminar el color y utilizar esta:

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

    <ItemGroup> 
    </ItemGroup> 

    <Target Name="Main"> 
    <Message Text="Color: %(Colors.Shade) %(Colors.Identity)"/> 
    </Target> 

</Project> 

Y SALIDAS:

Color: 

¿Por qué se está ejecutando un lote de la tarea de Mensaje cuando no hay elementos en el grupo? Hubiera esperado cero elementos, el lote se ejecutaría cero veces y no vería "Color:" seguido de nada en la salida.

¿Estoy haciendo algo mal o hay una solución para esto?

Gracias.


Actualización: que he encontrado que puede hacer:

<Message Condition="'@(Colors)'!=''" Text="Color: %(Colors.Shade) %(Colors.Identity)"/> 

Pero, si se siente insatisfactoria a tener que escribir código de forma explícita para el caso en que no hay elementos que se utiliza cada vez que la dosificación.

+0

Pregunta bien formulada. +1 –

Respuesta

11

Mis 2 centavos:

En su mensaje de tareas, no hay información de procesamiento por lotes y la información estática ("Colores:"). Creo que MsBuild imprime la información estática y luego realiza un lote sobre los valores de su artículo de colores. El problema es que no tiene ningún dato en su colección (incluso está no declarado), supongo que MsBuild interpreta esto como una lista vacía, que, cuando intente imprimirlo, imprima la cadena vacía ''.

Si elimina el contenido estático ("Colores:" y el espacio en blanco antes de la identidad), no se mostrará nada.

Una solución para la impresión con procesamiento por lotes solamente si los artículos colección no está vacía sería o bien:

  1. Comprobar si la colección está vacía

    <Message Condition="'@(Colors)'!=''" Text="Color: %(Colors.Shade) %(Colors.Identity)"/> 
    
  2. Uso Transformar [1]

    <Message Text="@(Colors->'Color : %(Shade) %(Identity)')"/> 
    

[1] http://msdn.microsoft.com/en-us/library/ms171476.aspx

+0

Gracias, eso es información útil. Sí, si elimino el bit estático "Colores:", entonces funciona bien. De hecho, estoy usando esto en una tarea de Exec para llamar a una herramienta de línea de comandos para un grupo de archivos. Eso necesita un contenido estático para que los argumentos pasen a la herramienta de línea de comandos, así que sí, como dices, parece que tengo que tener mucho cuidado para incluir Condition = "'(@ Colors)'! = ''" En todos los lugares donde uso esta técnica. –

4

Solo quería agregar una solución alternativa para esto también. Si puede cambiar el procesamiento por lotes al lote por lotes, en lugar del procesamiento por lotes por tareas, puede agregar su estado de condición al objetivo.

he añadido el procesamiento por lotes de destino aquí:

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

    <ItemGroup> 
    </ItemGroup> 

    <Target Name="Main" Outputs="%(Colors.Identity)"> 
    <Message Text="Color: %(Colors.Shade) %(Colors.Identity)"/> 
    </Target> 

</Project> 

...y que se puede realizar condicionalmente para que solo se ejecute cuando exista algo en el grupo de elementos Colores:

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

    <ItemGroup> 
    </ItemGroup> 

    <Target Condition="'@(Colors)'!=''" Name="Main" Outputs="%(Colors.Identity)"> 
    <Message Text="Color: %(Colors.Shade) %(Colors.Identity)"/> 
    </Target> 

</Project>