web-dev-qa-db-fra.com

Inclusion de fichiers de contenu dans .csproj hors du cône de projet

J'ai un projet C # dire MyProject.csproj situé dans "C:\Projects\MyProject \". J'ai également des fichiers que je veux copier dans le répertoire de sortie de ce projet. Mais les fichiers se trouvent à l’emplacement "C:\MyContentFiles \", c’est-à-dire qu’ils ne sont PAS dans le cône du projet. Ce répertoire contient également des sous-répertoires. Le contenu du répertoire n'est pas géré. Par conséquent, je dois inclure tout ce qui se trouve en dessous.

Lorsque je les inclut en tant que "Contenu" dans le projet, ils sont copiés, mais la structure de répertoires est perdue. J'ai fait quelque chose comme ça: -

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

Comment copier ces fichiers/répertoires de manière récursive dans le répertoire de sortie du projet avec la structure de répertoires préservée?

64
Poulo

Vous devez ajouter le fichier sous forme de lien:

  1. Faites un clic droit sur le projet dans VS.
  2. Ajouter -> Article existant ...
  3. Trouvez le fichier.
  4. Sélectionnez-le et.
  5. Ajouter en tant que lien (déroulant dans le bouton Ajouter de la boîte de dialogue).
  6. Ouvrez les propriétés du fichier et réglez "Copier dans le répertoire de sortie" sur "Copier toujours".

MAIS vous ne pouvez pas le faire pour l’arborescence.
Au lieu de cela, vous devez écrire une tâche post-build pour cela. Ceci est un échantillon qui va vous faire regarder.

40
Dmytrii Nagirniak

Je crois que @Dmytrii a tout à fait raison - vous souhaitez utiliser la fonction "lien".

Cependant, il n'a que partiellement raison de dire que vous ne pouvez pas créer de lien vers une arborescence de répertoires ..__ Bien que ce soit le cas lorsque vous essayez d'ajouter des liens à l'aide de l'interface graphique de Visual Studio, MSBuild le permet.

Si vous souhaitez conserver la structure de répertoires, ajoutez simplement la balise %(RecursiveDir) à votre noeud <link>:

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

La page Métadonnées d'élément bien connues de MSBuild donne plus de détails sur les métadonnées auxquelles vous pouvez accéder.

125
Mandark

La réponse de Mandark ajoute les fichiers de contenu directement à la solution et ils apparaîtront dans l'explorateur de la solution. Lorsqu'un fichier est ajouté ou supprimé dans le répertoire d'origine, Visual Studio ne le prend pas automatiquement. En outre, chaque fois qu'un fichier est supprimé ou ajouté dans l'explorateur de la solution, le fichier de projet est modifié et tous les fichiers sont inclus séparément, au lieu d'inclure le dossier.

Pour éviter cela, vous pouvez utiliser la même astuce, mais placez-le dans un fichier de projet séparé, puis importez-le.

Le fichier de projet (par exemple, include.proj) ressemble à ceci:

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

Dans votre propre fichier de projet, ajoutez la ligne suivante

<Import Project="include.proj" />

Visual Studio ne plaisante pas avec ce fichier et ajoute simplement des fichiers en tant que contenu lors d'une construction. Les modifications apportées au répertoire d'origine sont toujours incluses. Les fichiers n'apparaîtront pas dans l'explorateur de votre solution, mais seront inclus dans le répertoire de sortie.

Repris cette astuce ici: http://blogs.msdn.com/b/shawnhar/archive/2007/06/06/wildcard-content-using-msbuild.aspx

25

Ce qui suit, que vous ajouteriez au bas de votre fichier de projet, copiera vos fichiers de contenu en conservant la structure de répertoires dans un événement après la construction dans le répertoire cible $(TargetDirectory) de votre construction (généralement $(MSBuildProjectDirectory)\bin\Debug). 

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

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

Si ces fichiers doivent aller dans un répertoire nommé MyContentFiles, vous pouvez ajouter ceci avant la copie:

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

et changer

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

À

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

Je pense 

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

Est-ce juste, puisque vous voulez tout dans le dossier et les sous-dossiers

3
Menzi

Pour inclure des fichiers dans un dossier d'un projet .NET Core,

<ItemGroup>
  <None Update="..\..\MyContentFiles\**\*.*">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

Et la propriété des éléments "Copier dans le répertoire de sortie" sera "Copier si plus récent":
Copy if newer

0
zwcloud

Pour ignorer un fichier dans un projet .Net Core:

<ItemGroup>
 <Content Include="appsettings.local.json">
   <CopyToOutputDirectory Condition="Exists('appsettings.local.json')">PreserveNewest</CopyToOutputDirectory>
 </Content>
</ItemGroup>
0
Skorunka František