Compresi i file di contenuto in .csproj che si trovano all'esterno del cono del progetto


86

Ho un progetto C # ad esempio MyProject.csproj situato in "C: \ Projects \ MyProject \". Ho anche dei file che voglio copiare nella directory di output di questo progetto. Ma i file si trovano nella posizione "C: \ MyContentFiles \", cioè NON sono all'interno del cono del progetto. Questa directory ha anche delle sottodirectory. Il contenuto della directory non è gestito. Quindi devo includere tutto ciò che c'è sotto.

Quando li includo come "Contenuto" nel progetto, vengono copiati, ma la struttura della directory viene persa. Ho fatto qualcosa del genere: -

<Content Include="..\..\MyContentFiles\**">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

Come faccio a copiare questi file / directory in modo ricorsivo nella directory di output del progetto mantenendo la struttura della directory?

Risposte:


56

Devi aggiungere il file come collegamento:

  1. Fare clic con il tasto destro sul progetto in VS.
  2. Aggiungi -> Articolo esistente ...
  3. Trova il file.
  4. Selezionalo e.
  5. Aggiungi come collegamento (menu a discesa nel pulsante Aggiungi nella finestra di dialogo).
  6. Aprire le proprietà del file e impostare "Copia nella directory di output" su "Copia sempre".

MA non puoi farlo per l'albero delle directory.
Invece devi scrivere un'attività post-build per questo. Questo è un campione che ti farà fissare.


8
Come affermato in questa risposta , "Non puoi farlo per l'albero delle directory". l'affermazione non è vera.
Mandark

164

Credo che @Dmytrii abbia ragione da un lato: vuoi usare la funzione "link".

Tuttavia, ha solo parzialmente ragione quando dice che non è possibile collegarsi a un albero di directory. Anche se questo è vero quando si tenta di aggiungere i collegamenti utilizzando la GUI di Visual Studio, MSBuild lo supporta.

Se vuoi preservare la struttura della directory, aggiungi semplicemente il %(RecursiveDir)tag al tuo <link>nodo:

<Content Include="..\..\MyContentFiles\**\*.*">
  <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

La pagina MSBuild Well-known Item Metadata fornisce maggiori dettagli sui metadati a cui puoi accedere.


1
1) Cosa succede se un file viene eliminato dall'archivio risorse condivise? Non sembra che verrà eliminato da Solution Dir 2) Esiste un modo per ottenere Visual Studio per eliminare questi file da $ (SolutionDir) al termine dell'esecuzione. Lasciarli lì potrebbe confondere gli altri sviluppatori.
Adam

@Adam Vedi la mia risposta qui sotto
Robin van der Knaap

9
Essendo stato schiantato nel deserto con poco cibo, acqua e avendo il forte bisogno di compagnia, trovo che questa risposta sia utile. Seguendo queste istruzioni, sono stato in grado di costruire un'IA completamente funzionale che ora ha sostituito tutti i bisogni umani che una volta mi perseguitavano nella natura selvaggia qui. Grazie Mandark!
elemento profondo

1
@Vijay vedi la mia modifica, hai bisogno <Content Include="..\..\MyContentFiles\**\*.*">- nota \*.*alla fine del percorso.
CAD tipo

3
Non funziona per un progetto .NET Core su VS2017 (15.8.6).
zwcloud

29

La risposta di Mandark aggiunge i file di contenuto direttamente alla soluzione e verranno visualizzati in Esplora soluzioni. Ogni volta che un file viene aggiunto o eliminato nella directory originale, questo non viene raccolto automaticamente da Visual Studio. Inoltre, ogni volta che un file viene eliminato o aggiunto in Esplora soluzioni, il file di progetto viene modificato e tutti i file vengono inclusi separatamente, invece di includere solo la cartella.

Per evitare ciò, puoi usare lo stesso trucco, ma metterlo in un file di progetto separato e quindi importarlo.

Il file di progetto (ad esempio include.proj) ha questo aspetto:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Content Include="..\..\MyContentFiles\**">
  <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

Nel tuo file di progetto, aggiungi la seguente riga

<Import Project="include.proj" />

Visual Studio non interferirà con questo file e aggiunge semplicemente i file come contenuto durante una compilazione. Le modifiche nella directory originale sono sempre incluse. I file non verranno visualizzati in Esplora soluzioni, ma verranno inclusi nella directory di output.

Ho scoperto questo trucco qui: http://blogs.msdn.com/b/shawnhar/archive/2007/06/06/wildcard-content-using-msbuild.aspx


1
Per qualche motivo, questo non sembrava funzionare per me utilizzando un file .proj, ma sono riuscito a farlo funzionare con un file .csproj.
StriplingWarrior

6
È possibile aggiungere <Visible> true </Visible> all'elemento Content per visualizzare gli elementi in Esplora soluzioni.
Michael Baker

Il mio andava bene con solo un .proj
Jason Dufair

Questo non ha funzionato affatto per me e presumo sia perché gli stessi elementi da collegare sono stati generati in un evento di pre-costruzione.
Paul K

2
Non funziona per un progetto .NET Core su VS2017 (15.8.6).
zwcloud

11

Quanto segue, che aggiungeresti in fondo al tuo file di progetto, copierà i tuoi file di contenuto mantenendo la struttura della directory in un evento dopo la compilazione nella directory $(TargetDirectory)di destinazione della tua build (in genere $(MSBuildProjectDirectory)\bin\Debug).

<ItemGroup>
    <ExtraContent Include="$(MSBuildProjectDirectory)\..\..\MyContentFiles\**" />
</ItemGroup>

<Target Name="AfterBuild">
    <Copy 
        SourceFiles="@(ExtraContent)" 
        DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" 
        SkipUnchangedFiles="true" />
</Target>

Se questi file dovevano andare in una directory denominata MyContentFiles, puoi aggiungerlo prima della copia:

<MakeDir Directories="$(TargetDir)\MyContentFiles" Condition=" !Exists('$(TargetDir\MyContentFiles') " />

e cambiare

<Copy 
            SourceFiles="@(ExtraContent)" 
            DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" 
            SkipUnchangedFiles="true" />

Per

<Copy 
            SourceFiles="@(ExtraContent)" 
            DestinationFiles="@(ExtraContent->'$(TargetDir)\MyContentFiles\%(RecursiveDir)%(Filename)%(Extension)')" 
            SkipUnchangedFiles="true" />

1
Le tue trasformazioni hanno un tipo o: @ (ExtraContent) -> '...') dovrebbe essere @ (ExtraContext -> '...'). Altrimenti buona risposta!
alexdej

@Todd 1) Cosa succede se un file viene eliminato dall'archivio MyContentFiles? Non sembra che verrà eliminato da Solution Dir 2) Esiste un modo per ottenere Visual Studio per eliminare questi file da $ (SolutionDir) al termine dell'esecuzione. Lasciarli lì potrebbe confondere gli altri sviluppatori.
Adam

Questo era ciò di cui avevo bisogno. Il progetto e il processo di compilazione ora funzionano come previsto, ma i file non vengono pubblicati con un clic dell'applicazione. Qualche suggerimento per questo?
Georg W.

4

credo

<Content Include="..\..\MyContentFiles\**\*.*">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

È appena sufficiente, dal momento che vuoi tutto in quella cartella e sottocartelle


3

Per includere file in una cartella per un progetto .NET Core,

<!--Just files-->
<ItemGroup>
  <None Update="..\..\MyContentFiles\**\*.*">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>
<!--Content files-->
<ItemGroup>
  <Content Include="..\..\MyContentFiles\**\*.*" Link="MyContentFiles\%(RecursiveDir)%(Filename)%(Extension)">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </Content>
</ItemGroup>

E la proprietà degli elementi "Copia nella directory di output" sarà "Copia se più recente":
Copia se più recente


-1

Per ignorare un file in un progetto .Net Core:

<ItemGroup>
 <Content Include="appsettings.local.json">
   <CopyToOutputDirectory Condition="Exists('appsettings.local.json')">PreserveNewest</CopyToOutputDirectory>
 </Content>
</ItemGroup>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.