2008-11-12 21 views
20

Soy nuevo en MSBuild y quería jugar un poco con él, pero no puedo entender por qué esto no funciona.¿Usa tareas personalizadas de MSBuild desde la misma solución?

Así que mi solución tiene dos proyectos: "Modelo" y "BuildTasks". BuildTasks acaba de 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 añadido esto:

<UsingTask TaskName="BuildTasks.Test" AssemblyFile="$(SolutionDir)src\BuildTasks\bin\BuildTasks.dll" /> 
    <Target Name="AfterBuild"> 
    <Test /> 
    </Target> 

He creado la orden de construcción de manera "BuildTasks" se construyó antes " Modelo". Pero cuando intento de construir Modelo consigo este error:

The "BuildTasks.Test" task could not be loaded from the assembly C:\WIP\TestSolution\src\BuildTasks\bin\BuildTasks.dll. Could not load file or assembly 'file:///C:\WIP\TestSolution\src\BuildTasks\bin\BuildTasks.dll' or one of its dependencies. The system cannot find the file specified. Confirm that the <UsingTask> declaration is correct, and that the assembly and all its dependencies are available.

definitivamente este archivo existe, ¿por qué no puedo MSBuild encontrarlo?

Incluso he intentado con la codificación rígida "C: \ WIP \ TestSolution" en lugar de "$ (SolutionDir)" y obtengo el mismo error. Sin embargo, si copio ese archivo .dll en mi escritorio y codigo la ruta a mi escritorio, FUNCIONA, lo que no puedo entender por qué.

EDIT: 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.

+3

¿Pudo resolver el problema? Tengo el mismo problema. – sean

+0

3 años sin una resolución? Tengo este problema pero esta publicación no sirve de nada, ya que no está claro si el problema se resolvió alguna vez ... – DaveN59

Respuesta

2

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> 
+0

@Tinister: según su edición anterior, usar $ (Configuración) en la ruta es la correcta, ya que será 'Release' o 'Debug' (o cualquier otro nombre que use) – gregmac

10

Probamos y nos pareció que tiene que colocar el 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 de MSBuild separado 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 
      &quot;$(MSBuildProjectDirectory)\PostBuild.msbuild&quot; 
      /property:SomeProperty=$(SomeProperty)" /> 
</Target> 

Tenga en cuenta que puede pasar propiedades a esta tarea de subcompilación en la línea de comandos.

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> 
+0

Muchas gracias, funciona a lo grande. – daljit

0

El bloqueo de los archivos DLL de tareas personalizados puede evitarse si todas las tareas personalizados heredan de AppDomainIsolatedTask y si se establece la variable de entorno MSBUILDDISABLENODEREUSE = 1 antes de iniciar Visual Studio.

El ensamblaje 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 Task.

Por otro lado, si solo hereda de AppDomainIsolatedTask y no establece MSBUILDDISABLENODEREUSE, los procesos inactivos de MSBuild seguirán bloqueando el ensamblaje.

+1

¿Puedes explicar un poco más? –

+0

He ampliado la respuesta. – user400144

Cuestiones relacionadas