Personalización de una compilación para controlar los archivos generados

En cualquier compilación, los archivos que se generan durante la misma se comportan de forma diferente a los archivos estáticos (como los archivos fuente). Por este motivo, es importante comprender cómo MSBuild compila proyectos. Las dos fases son la fase de evaluación y la fase de ejecución. Durante la fase de evaluación, MSBuild lee el proyecto, lo importa todo, crea propiedades, expande los globs de los elementos y configura el proceso de compilación. Durante la fase de ejecución, MSBuild realiza la compilación ejecutando destinos y tareas con los datos analizados durante la fase de evaluación.

Los archivos generados durante la ejecución no existen durante la fase de evaluación, por lo que no se incluyen en el proceso de compilación. Para solucionar este problema, hay que añadir manualmente los archivos generados al proceso de compilación. La manera recomendada de hacerlo es añadiendo el nuevo archivo a los elementos Content o None antes del destino BeforeBuild, como en el ejemplo siguiente:

<Target Name="MyTarget" BeforeTargets="BeforeBuild">
  
  <!-- Some logic that generates your file goes here -->
  <!-- Generated files should be placed in $(IntermediateOutputPath) -->

  <ItemGroup>
    <!-- If your generated file was placed in `obj\` -->
    <None Include="$(IntermediateOutputPath)my-generated-file.xyz" CopyToOutputDirectory="PreserveNewest"/>
    <!-- If you know exactly where that file is going to be, you can hard code the path. -->
    <None Include="some\specific\path\my-generated-file.xyz" CopyToOutputDirectory="PreserveNewest"/>
    
    <!-- If you want to capture "all files of a certain type", you can glob like so. -->
    <None Include="some\specific\path\*.xyz" CopyToOutputDirectory="PreserveNewest"/>
    <None Include="some\specific\path\*.*" CopyToOutputDirectory="PreserveNewest"/>
  </ItemGroup>
</Target>

Basta con agregar el archivo generado a None o Content para que el proceso de compilación lo vea. También hay que asegurarse de añadirlo en el momento adecuado. Lo ideal es que el destino se ejecute antes de BeforeBuild. AssignTargetPaths es otro destino posible, ya que es la última oportunidad de modificar los elementos None y Content (entre otros) antes de transformarlos en nuevos elementos. Consulte Tipos de elemento comunes.