Visual Studio: Comment «copier dans le répertoire de sortie» sans copier la structure des dossiers?


111

J'ai quelques fichiers dll dans le dossier \ lib de mon dossier de projet. Dans la page de propriétés de dll, j'ai sélectionné "Build Action" comme "Content" et "Copy to Output Directory" comme "Copy always".

Après la construction, je reçois en fait la dll copiée mais elles sont à l'intérieur de \ bin \ Release \ lib et non dans \ bin \ Release.

Existe-t-il un moyen de copier des fichiers dll dans \ bin \ Release (et non dans \ bin \ Release \ lib) sans écrire un script post-build ou recourir à nant, etc.?

Réponses:


256

au lieu d' <Content>utiliser <ContentWithTargetPath>et de spécifier le chemin cible, comme ceci:

<ItemGroup>
  <ContentWithTargetPath Include="lib\some_file.dat">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <TargetPath>some_file.dat</TargetPath>
  </ContentWithTargetPath>
</ItemGroup>

Notez que cette entrée peut ne pas être visible à partir de Visual Studio (2012, 2015, 2017), mais une fois ajoutée manuellement au csproj, elle apparaîtra dans Visual Studio. Le chemin cible ne sera cependant pas modifiable via l'interface utilisateur.


2
Je ne vois pas ContentWithTargetPath comme option d'action de construction dans VS 2015. Existe-t-il un moyen de l'ajouter?
Kim

1
Une fois que j'ai ajouté manuellement l'entrée dans le fichier .csproj, elle apparaît comme une option dans l'EDI. Cependant, je ne peux toujours pas modifier le chemin cible à partir de l'EDI.
Kim

9
Mon seul souci est que cela ne sera plus pris en charge avec les futures versions de MSBuild / .NET / Visual Studio / Whatever, puisque l'interface utilisateur de VS2015 n'affiche pas cette option ou la propriété TargetPath.
MarioDS

1
Cela fonctionne pour moi. Aucune des autres réponses ne fonctionne pour moi. Cela devrait être la réponse.
GunWanderer

1
Notez que l'utilisation de ContentWithTargetPathla compilation incrémentielle des pauses (testé sur VS 2017 15.9.9)
Mads Ravn

26

Gardez-les $(ProjectDir)\Lib, mais ajoutez ces fichiers " En tant que lien " à la racine de votre .csproj. Maintenant, ils seront copiés dans bin \ Debug (ou dans tout autre dossier de sortie) sans être dans lib.

EDIT: Cette réponse a été écrite il y a longtemps lorsque ContentWithTargetPath n'était pas disponible dans les versions de VS / MSBuild que j'utilisais. Laisser cette réponse ici pour les personnes qui pourraient avoir à utiliser une ancienne version de VS. Veuillez arrêter de commenter cela, nous savons tous qu'il existe de meilleures façons maintenant.


4
Merci ananthonline. J'ai essayé vos pas mais cela n'a pas aidé. Peut-être que je fais quelque chose de mal. Voici ce que je fais, veuillez corriger si vous pensez que quelque chose est incorrect: 1. Excluez ces DLL du projet mais laissez-les être dans la bibliothèque 2. Faites un clic droit sur le projet et "Ajouter des éléments existants". Sélectionnez les dll de la bibliothèque et ajoutez-les "en tant que lien" 3. Faites un clic droit sur les dll et sélectionnez à nouveau "Copier toujours" dans "Copier dans le répertoire de sortie". 4. Nettoyer et reconstruire. Résultat: j'ai de nouveau ces dll dans \ bin \ release \ lib
OhDear

1
Veuillez poster une capture d'écran de votre dossier de solution après l'avoir configuré
Ani

3
Si j'essaie d'ajouter un lien vers un fichier déjà dans l'arborescence du projet, il refuse et inclut simplement le fichier dans le projet à nouveau ...
Nyerguds

1
Comme @Nyerguds, je constate que vous ne pouvez pas ajouter de lien vers un fichier qui se trouve déjà dans l'arborescence du projet, donc cette réponse ne résout pas la question.
Tore Østergaard

1
Cela n'inonde-t-il pas la racine du répertoire du projet dans l'Explorateur de solutions? Avec de nombreux fichiers de ce type, cela peut être un problème. Habituellement, la racine d'un répertoire de projet contient déjà trop de fichiers divers.
Alex34758

10

Si votre intention principale est d'inclure des DLL sans encombrer le répertoire racine du projet, une autre solution consiste à déplacer les DLL vers un projet partagé distinct et à l'ajouter comme référence dans le projet d'origine.

(Notez que cet article ne répond pas directement à cette question car il ne préserve pas la structure du dossier et du projet, mais j'ai trouvé cette approche utile car j'ai pu restructurer mon projet dans mon cas et parce que je voulais éviter certains des inconvénients des autres approches ici.)

Pas

  • Cliquez avec le bouton droit sur votre Solution -> Add -> New Project -> Shared Project
  • Ajoutez les DLL à ce projet (dans le répertoire racine de ce projet, pas dans un sous-dossier "lib")
  • (Vérifiez que les propriétés du fichier DLL sont correctement définies, par exemple Build Action: Contentet Copy to Output Directory: Copy Always)
  • Cliquez avec le bouton droit sur le projet d'origine References -> Add Reference -> Shared Projects
  • Sélectionnez le projet partagé que vous avez créé précédemment

La configuration ressemble à ceci:

solution-explorer-screenshot


2
De loin la solution simple et élégante pour garder le projet épuré.
Ravi Ganesh

Je n'ai pas pu le faire fonctionner avec les fichiers UAP et * .bin.
Matteo le

7

Ajoutez les fichiers dll en tant que référence au projet et sur le jeu de référence «Copier local» sur true.


1
Merci Erik. Cela fonctionne parfaitement, sauf pour une dll que je ne peux pas ajouter comme référence. L'erreur que j'obtiens lors de l'ajout comme référence est qu'une référence à «libeay32.dll» n'a pas pu être ajoutée. Assurez-vous que le fichier est accessible et qu'il s'agit d'un assemblage ou d'un composant COM valide.
OhDear le

7
@MAnthony: seuls les assemblys .NET ou les assemblys d'interopérabilité COM peuvent être ajoutés en tant que références de projet; les DLL natives ne peuvent pas être. Vous devrez trouver un autre moyen de copier la DLL dans \ bin \ Release.
Michael Liu

Merci Erik et Michael et ananthonline. Désolé, je ne peux pas voter pour vos réponses et commentaires car je n'ai pas les points de réputation requis.
OhDear le

1
Pour la DLL non gérée, vous devrez utiliser la méthode suggérée ci-dessous.
Ani le

4

Si vous devez copier des fichiers du répertoire Libs vers le dossier racine VS2017:

<ItemGroup Condition="'$(Platform)' == 'x64'">
    <None Include="Libs\x64\**" Link="\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup Condition="'$(Platform)' == 'x86'">
    <None Include="Libs\x86\**" Link="\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

Vers tout autre dossier, y compris le dossier Libs (RecursiveDir)

<ItemGroup Condition="'$(Platform)' == 'x86'">
    <None Include="Libs\x86\**" Link="mycustomfolder\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

3

Il semble dans VisualStudio 2015 que si les dll que vous ajoutez avec un lien se trouvent dans un sous-dossier de ce même projet - elles seront automatiquement placées dans un dossier et la sortie est également placée dans un dossier comme vous l'avez vu.

Si les dll sont dans un autre projet ou répertoire sur le disque pas dans un sous-dossier du projet , vous pouvez «Ajouter avec un lien», et ils seront placés dans le répertoire racine très bien.


Idem dans VS2012. Il refuse d'en faire un lien et les ajoute simplement en tant que contenu. En fin de compte, la solution la plus simple semble être de les vider à la racine du projet.
Nyerguds le

0

Une autre méthode consiste simplement à laisser les éléments en tant que type None. Dans l'explorateur de solutions, cliquez sur ceux que vous souhaitez déployer et définissez la Contentpropriété sur True.

Remarque: j'ai fait cela dans VS2019, et les choses peuvent changer d'une version à l'autre.

Pour que cela fonctionne, faites maintenant un clic droit sur votre projet et sélectionnez «Décharger le projet». Cliquez ensuite avec le bouton droit sur le projet déchargé et sélectionnez "Editer nom_projet.vcxproj".

Dans l'éditeur, allez jusqu'au bas du fichier et insérez cette cible juste avant la </Project>balise de fin :

  <Target Name="CopyContent" AfterTargets="Build">
    <Copy SourceFiles="@(None)" Condition="'%(None.DeploymentContent)' == 'true'" DestinationFolder="$(OutputPath)" ContinueOnError="true" />
  </Target>

Maintenant, faites un clic droit sur le projet déchargé et sélectionnez "Recharger le projet". Sélectionnez pour enregistrer et fermer si vous y êtes invité.

J'ai également défini le OutputDirectorysur:

$(SolutionDir)bin\$(Configuration)\$(Platform)\

et le IntermediateDirectoryà:

$(SolutionDir)obj\$(Configuration)\$(ProjectName)\$(Platform)\

dans la page Général des propriétés du projet. Cela place la sortie dans un dossier «bin» et les intermédiaires dans un dossier «obj» à la racine de votre solution.

Remarque: Le $(SolutionDir)n'est pas défini lorsque vous exécutez MSBuild à partir de la ligne de commande. Il existe une astuce que vous pouvez utiliser pour définir cela dans le dossier où se trouve le fichier .sln à l'aide de GetDirectoryNameOfFileAbove. (à gauche comme exercice pour le lecteur). En outre, il semble qu'en 2019, ils gèrent cela correctement sur la ligne de commande de toute façon. Ouais :) Le $(SolutionDir)contient une barre oblique inverse de fin, donc aucune après. Les résultats de chacun doivent avoir une barre oblique inverse de fin.

Maintenant, si vous possédez Pro ou supérieur, veuillez ne pas le faire chaque fois que vous devez créer un projet. Ce serait nul. Au lieu de cela, une fois que vous avez configuré votre projet comme vous l'aimez, sélectionnez Project -> Export Template. Vous lui donnez un nom, et la prochaine fois que vous voudrez créer un projet comme celui-là, choisissez simplement ce nom dans la boîte de dialogue Nouveau projet. (Dans l'ancienne version, je pense que c'était le cas Files -> Export Teamplate....)


-1

J'ai eu le même problème avec Visual Studio 2010 / C # Project.

Pour les assemblys (c'est-à-dire ayant l'interface .NET), utilisez le dossier "Références" sous votre projet dans l'Explorateur de solutions. Faites un clic droit dessus, choisissez "Ajouter un élément existant" et recherchez votre assembly .dll.

Les fichiers .dll courants peuvent être placés dans un sous-dossier (comme "\ lib" a été mentionné ci-dessus) et dans les propriétés, sélectionnez:

  • Build Action = "HelpFiles"
  • Copy To OutputDirectory = "Si plus récent"

Cela a fonctionné pour moi exactement comme souhaité - lors de la construction, les .DLL sont copiés dans le répertoire de sortie sans le sous-dossier "\ lib".

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.