2010-08-03 14 views
10

Creé un objetivo común personalizado "RealClean" que elimina todos los archivos en el directorio de salida y "salida intermedia". Lo puse en el archivo Microsoft.Common.targets. Cuando ejecuto MsBuild en mi csproj todo está bien. Pero cuando corro MSBUILD en mi sln (que simplemente hace referencia a una lista de csproj) Tengo el siguiente errorObjetivo común personalizado para generar una solución

error MSB4057: The target "RealClean" does not exist in the project. 

Aquí está la línea de comandos entro a correr MSBUILD

C:\Windows\Microsoft .NET\Framework\v3.5\MsBuild.exe /p:Configuration="Release";OutputPath="..\..\MSBuild.Referentiel.net35";nowarn="1591,1573" /t:RealClean mySolution.sln 

Cualquier pista?

Respuesta

5

para trabajar en archivo de solución, MSBuild crea un archivo de proyecto de MSBuild temporal que contiene sólo algunos objetivos como Build y Limpio. Por lo tanto, no puede llamar a su destino personalizado en un archivo de solución.

+1

Ok, lo tengo. Ingresé a este archivo de proyecto temporal e incluye Compilar, Limpiar, Reconstruir y Publicar. No importa desde common.targets.files. Lástima, tendré que encontrar otra solución. –

+0

Esto no se aplica a ninguna compilación de Visual Studio, ¿verdad? – Maslow

5

Madgnome probablemente tenga razón. Pero quería agregar que no debería estar editando los archivos Microsoft.common.targets. Si lo hace, corre el riesgo de tener un proceso de compilación diferente en esa máquina en comparación con lo que todos los demás tienen. En su caso, podría haber creado un nuevo archivo MSBuild con solo el objetivo RealClean y lo colocó en C: \ Archivos de programa (x86) \ MSBuild \ v4.0 \ Custom.After.Microsoft.Common.tarmon o por 32 bit C: \ Archivos de programa \ MSBuild \ v4.0 \ Custom.After.Microsoft.Common.targets y esencialmente eso sería lo mismo que poner ese archivo dentro de Microsoft.Common.targets, excepto que no lo hagas t tiene que modificar ese archivo.

+0

¡Gracias!Eso será más limpio. –

+0

¿Hay alguna manera de hacer esta modificación en el nivel de solución en lugar de en la máquina? – Maslow

15

Tuve el mismo problema pero no quería modificar las cosas fuera del árbol de fuentes para que esto funcione. Agregar archivos a C: \ Archivos de programa ... significa que debe hacerlo manualmente en cada máquina de desarrollo para obtener el mismo comportamiento.

lo hice tres cosas:

1) crea un archivo objetivos personalizados que he importación en todas y cada una o # proyecto/VB/F C# en mi solución añadiendo el siguiente para cada archivo proj:

<!-- Rest of project file --> 

<PropertyGroup Condition="'$(SolutionDir)' == '' or '$(SolutionDir)' == '*undefined*'"> 
    <!-- Relative path to containing solution folder --> 
    <SolutionDir>..\</SolutionDir> 
</PropertyGroup> 
<Import Project="$(SolutionDir)CommonSettings.targets" /> 

2) Añadido un blanco limpio, que es llamada después de que el verdadero limpio (usando los AfterTargets atributo de MSBuild 4.0):

<Target Name="CleanCs" AfterTargets="Clean"> 
    <Message Text="Deep cleaning C# project..." /> 
    <CreateItem Include="$(OutDir)**\*.*; $(ProjectDir)\obj\**\*.*; $(IntermediateOutputPath)**\*.*" 
          Exclude="**\bin\**\*.vshost.exe; $(IntermediateOutputPath)**\*.log"> 
     <Output TaskParameter="Include" ItemName="AfterClean_FilesToDelete"/> 
    </CreateItem> 
    <Delete Files="@(AfterClean_FilesToDelete)" /> 
    <CreateItem Include="$(ProjectDir)\obj\" > 
     <Output TaskParameter="Include" ItemName="AfterClean_DirectoriesToDelete" /> 
    </CreateItem> 
    <CreateItem Include ="$(ProjectDir)\bin\" Condition="'$(TargetExt)' != '.exe'" > 
     <Output TaskParameter="Include" ItemName="AfterClean_DirectoriesToDelete"/> 
    </CreateItem> 
    <RemoveDir ContinueOnError="true" Directories="@(AfterClean_DirectoriesToDelete)" /> 
</Target> 

3) En mi proyecto de MSBuild integración continua I compruebe y asegúrese de que todos los archivos de proj tengan # 1:

<ItemGroup> 
    <!-- Exclude viewer acceptance tests as they must compile as x86 --> 
    <CheckProjects_CsProjects Include="**\*.csproj" /> 
</ItemGroup> 
<Target Name="CheckProjects"> 
    <!-- 
     Look for C# projects that don't import CommonSettingsCs.targets 
    --> 
    <XmlRead XPath="//n:Project[count(n:Import[@Project[contains(string(), 'CommonSettingsCs.targets')]]) = 0]/n:PropertyGroup/n:AssemblyName/text() " 
     XmlFileName="%(CheckProjects_CsProjects.Identity)" 
     Namespace="http://schemas.microsoft.com/developer/msbuild/2003" 
     Prefix="n" > 
     <Output TaskParameter="Value" ItemName="CheckProjects_CsMissingImports"/> 
    </XmlRead> 
    <Error Text="Project missing CommonSettingsCs.targets: %(CheckProjects_CsMissingImports.Identity)" 
       Condition="'%(CheckProjects_CsMissingImports.Identity)' != ''" /> 
</Target> 

Esto evita que los desarrolladores se olviden de agregar # 1. Puede crear su propia plantilla de proyecto para asegurarse de que todos los proyectos nuevos tengan esto de forma predeterminada.

La ventaja de este enfoque es la configuración de un nuevo alistamiento de árbol de origen que no implica nada más que obtener el árbol de origen actual. La desventaja es que tiene que editar los archivos del proyecto una vez cuando los crea.

+0

¡Gracias! Pasé la mitad de la mañana buscando una solución decente para esto; su punto # 3 fue el eslabón perdido. – kenchilada

+1

Gracias. En todo caso, la propiedad 'AfterTargets' me puso en el camino correcto –

+0

Han pasado 7 años desde que se publicó esta respuesta. Si bien es bueno, me pregunto si ahora hay una manera menos detallada de hacer esto. – Nuzzolilo

Cuestiones relacionadas