2010-08-03 15 views
10

Ho creato un obiettivo comune personalizzato "RealClean" che rimuove tutti i file nell'output e nella directory "output intermedio". L'ho inserito nel file Microsoft.Common.targets. Quando eseguo MsBuild sul mio csproj tutto va bene. Ma quando ho eseguito MsBuild sul mio SLN (che appena fa riferimento a un elenco di csproj) ho il seguente erroreObiettivo comune personalizzato per creare una soluzione

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

Ecco la linea di comando io entro a correre MsBuild

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

Qualsiasi suggerimento?

risposta

5

di lavorare su file di soluzione, MSBuild crea un file di progetto MSBuild temporaneo contenente solo alcuni obiettivi come Costruire e Clean. Quindi non è possibile chiamare il target personalizzato su un file di soluzione.

+1

Ok ho capito. Sono entrato in questo file di progetto temporaneo e include Build, Clean, Rebuild and Publish. Nessuna importazione da common.targets.files. Peccato, dovrò trovare un'altra soluzione. –

+0

Questo non si applica a qualsiasi build di Visual Studio, giusto? – Maslow

5

Madgnome ha probabilmente ragione. Ma volevo aggiungere che non dovresti modificare i file Microsoft.common.targets. Se lo fai, rischi di avere un processo di compilazione diverso su quella macchina rispetto a quello che hanno tutti gli altri. Nel tuo caso potresti aver creato un nuovo file MSBuild con il solo target RealClean e metterlo a C: \ Programmi (x86) \ MSBuild \ v4.0 \ Custom.After.Microsoft.Common.targets o per 32 bit C: \ Programmi \ MSBuild \ v4.0 \ Custom.After.Microsoft.Common.targets e in sostanza sarebbe lo stesso di mettere quel file all'interno di Microsoft.Common.targets, tranne che non si ' Devo modificare quel file.

+0

Grazie!Quello sarà più pulito. –

+0

in qualsiasi modo ancora per fare questa modifica a livello di soluzione anziché a livello macchina? – Maslow

15

Ho avuto lo stesso problema ma non volevo modificare le cose all'esterno dell'albero di origine per farlo funzionare. Aggiungere file a C: \ Programmi ... significa che devi farlo manualmente su ogni macchina di sviluppo per ottenere lo stesso comportamento.

ho fatto tre cose:

1) ha creato un file di obiettivi personalizzati che ho importare in ogni C# e/o VB/F # progetto nella mia soluzione aggiungendo quanto segue a ogni file 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) ha aggiunto un obiettivo pulito che viene chiamato dopo che il vero Clean (utilizzando i AfterTargets attributo da 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) Nel mio integrazione continua di progetto MSBuild i controllare e assicurarsi che tutti i file proj hanno # 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> 

Questo impedisce agli sviluppatori di dimenticare di aggiungere # 1. Puoi creare il tuo modello di progetto per assicurarti che tutti i nuovi progetti abbiano questo di default.

Il vantaggio di questo approccio è la creazione di una nuova struttura di origine arruolamento non comporta nulla di più di ottenere l'albero dei sorgenti corrente. Lo svantaggio è che devi modificare i file di progetto una volta quando li crei.

+0

Grazie! Ho passato metà mattina cercando una soluzione decente a questo; il tuo punto # 3 era il collegamento mancante. – kenchilada

+1

Grazie. Se mai, la proprietà 'AfterTargets' mi ha dato il percorso giusto –

+0

Sono passati 7 anni da quando questa risposta è stata pubblicata. Mentre è buono, mi chiedo se ora c'è un modo meno verboso per farlo? – Nuzzolilo

Problemi correlati