.net - studio - ¿Usa tareas personalizadas de MSBuild desde la misma solución?
visual studio installer (6)
Soy nuevo en MSBuild y quería jugar un poco con él, pero no puedo entender por qué esto no funciona.
Entonces mi solución tiene dos proyectos: "Modelo" y "BuildTasks". BuildTasks solo tiene una sola clase:
using Microsoft.Build.Utilities;
namespace BuildTasks
{
public class Test : Task
{
public override bool Execute()
{
Log.LogMessage( "FASDfasdf" );
return true;
}
}
}
Y luego en el Model.csproj he agregado esto:
<UsingTask TaskName="BuildTasks.Test" AssemblyFile="$(SolutionDir)src/BuildTasks/bin/BuildTasks.dll" />
<Target Name="AfterBuild">
<Test />
</Target>
Configuré el orden de compilación para que "BuildTasks" se construya antes de "Modelo". Pero cuando intento construir el Modelo, obtengo este error:
La tarea "BuildTasks.Test" no se pudo cargar desde el ensamblado C: / WIP / TestSolution / src / BuildTasks / bin / BuildTasks.dll. No se pudo cargar el archivo o ensamblado ''file: /// C: / WIP / TestSolution / src / BuildTasks / bin / BuildTasks.dll'' o una de sus dependencias. El sistema no puede encontrar el archivo especificado. Confirme que la declaración <UsingTask> es correcta y que el ensamblado y todas sus dependencias están disponibles.
Este archivo definitivamente existe, entonces ¿por qué MSBuild no puede encontrarlo?
Incluso he intentado codificar "C: / WIP / TestSolution" en lugar de "$ (SolutionDir)" y obtener el mismo error. Sin embargo, si copio ese .dll en mi escritorio y codigo el camino a mi escritorio, SI FUNCIONA , lo cual no puedo entender por que.
EDITAR : No tengo el camino equivocado. Modifiqué las compilaciones Debug / Release para BuildTasks para generar el .dll a la carpeta bin, ya que no quería que Debug / Release tuviera diferentes rutas.
¿Estás seguro de que tienes tu camino escrito? ¿No debería estar en el bin/Configuration Type/BuildTasks.dll
?
Encontré este enlace: http://bartdesmet.net/blogs/bart/archive/2008/02/15/the-custom-msbuild-task-cookbook.aspx muy útil al comenzar a escribir tareas de MSBuild.
Puede probar fuslogvw para diagnosticar el problema, pensó que no estaba claro si llegaba tan lejos ...
Probamos esto y descubrimos que debe colocar la tarea UsingTask en la parte superior del archivo del proyecto (y tener todas las rutas correctas). Sin embargo, una vez que esté en su lugar y la tarea se carga, solo funcionará una vez. Después de eso, la compilación comienza a fallar porque no puede copiar la DLL en la que se encuentra la tarea. De hecho, estamos ejecutando una tarea de compilación posterior dentro del mismo ensamblado / proyecto que estamos construyendo.
Lo que hicimos para resolver esto es lanzar un proceso separado de MSBuild en un archivo separado de MSBuild para ejecutar las tareas de Post Build. De esta forma, la DLL no se carga hasta después de su compilación y copia en el directorio bin.
<Target Name="AfterBuild">
<Exec Command="$(MSBuildBinPath)/MSBuild.exe
"$(MSBuildProjectDirectory)/PostBuild.msbuild"
/property:SomeProperty=$(SomeProperty)" />
</Target>
Tenga en cuenta que puede pasar propiedades a esta tarea de subcompilación en la línea de comando.
Y el PostBuild.msbuild se ve así:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="PostBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<UsingTask TaskName="PostBuild" AssemblyFile="$(MSBuildProjectDirectory)/bin/AssemblyThatJustBuiltAndContainsBuildTask.dll" />
<PropertyGroup>
<SomeProperty>SomePropertyDefaultValue</SomeProperty>
</PropertyGroup>
<Target Name="PostBuild">
<MyPostBuildTask SomeProperty="$(SomeProperty)" />
</Target>
</Project>
El bloqueo de las DLL de tareas personalizadas se puede evitar si todas las tareas personalizadas heredan de AppDomainIsolatedTask y si establece la variable de entorno MSBUILDDISABLENODEREUSE = 1
antes de iniciar Visual Studio.
El ensamblado con las tareas de compilación personalizadas está bloqueado tanto por devenv.exe como por msbuild.exe.
Puede hacer que los procesos msbuild.exe desaparezcan con MSBUILDDISABLENODEREUSE = 1
, pero devenv.exe aún bloqueará esporádicamente el ensamblado de tareas personalizadas si sus tareas personalizadas heredan de la Tarea .
Por otro lado, si solo hereda de AppDomainIsolatedTask y no establece MSBUILDDISABLENODEREUSE
los procesos inactivos de MSBuild seguirán bloqueando el ensamblaje.
La desactivación de la reutilización del nodo MSBuild también solucionará este problema:
- En la línea de comandos de MSBuild, pase la opción
/nr:false
. - Para Visual Studio, debe establecer la variable de entorno
MSBUILDDISABLENODEREUSE
en1
antes de iniciar VS.
Ver Visual Studio 2012 RTM tiene MSBuild.exe en memoria después de cerrar
Slace tenía razón. Es más que probable que su camino al ensamblado sea incorrecto. Y probablemente debería ser:
<UsingTask
TaskName="BuildTasks.Test"
AssemblyFile="$(SolutionDir)src/BuildTasks/bin/$(Configuration)/BuildTasks.dll" />
<Target Name="AfterBuild">
<Test />
</Target>