Comment faire en sorte que Visual Studio copie un fichier DLL dans le répertoire de sortie?

101

J'ai un projet Visual Studio C ++ qui repose sur un fichier DLL externe. Comment puis-je faire en sorte que Visual Studio copie automatiquement ce fichier DLL dans le répertoire de sortie (debug / release) lorsque je crée le projet?

Tapis
la source

Réponses:

91

Utilisez une action post-génération dans votre projet et ajoutez les commandes pour copier la DLL incriminée. L'action post-build est écrite sous forme de script batch.

Le répertoire de sortie peut être référencé comme $(OutDir). Le répertoire du projet est disponible sous la forme $(ProjDir). Essayez d'utiliser des chemins relatifs, le cas échéant, afin de pouvoir copier ou déplacer votre dossier de projet sans interrompre l'action post-génération.

Adrien Plisson
la source
26
Il convient également de souligner qu'il peut définir l'événement post-build via Projet> Propriétés> Événements de construction> Événement post-construction.
Phil Booth
37
Au cas où le lien serait rompu: "xcopy / y" $ (ProjectDir) *. Dll "" $ (OutDir) "
ace
J'ai changé ce qui précède pour utiliser personnellement la commande dans mes instances. Cette volonté; copiez les fichiers en lecture seule compatibles avec le contrôle de code source et créez le répertoire cible (normalement inutile). -> xcopy "$ (ProjectDir) *. dll" "$ (OutDir)" / i / r / y
Mangez chez Joes le
8
Ajoutez l'indicateur / d à xCopy pour éviter la recopie inutile des fichiers qui n'ont pas changé dans le répertoire de sortie.
Zoey
44

$ (OutDir) s'est avéré être un chemin relatif dans VS2013, j'ai donc dû le combiner avec $ (ProjectDir) pour obtenir l'effet souhaité:

xcopy /y /d  "$(ProjectDir)External\*.dll" "$(ProjectDir)$(OutDir)"

BTW, vous pouvez facilement déboguer les scripts en ajoutant «echo» au début et observer le texte développé dans la fenêtre de sortie de construction.

Nesho Neshev
la source
3
$ (TargetDir) peut remplacer $ (ProjectDir) $ (OutDir) car c'est de toute façon une combinaison des deux.
person27
Dans mon cas, sans le / d, il lançait une erreur d'accès refusé. Mais / d selon la documentation est pour la date. Je ne sais pas quelle est la connexion.
Ravi C
1
L'ajout de / d empêche l'écrasement si le fichier source est plus ancien ou identique à un fichier existant. L'erreur d'accès refusé peut se produire si la cible est verrouillée par un autre processus.
Rich Shealer
7

Les détails dans la section des commentaires ci-dessus ne fonctionnaient pas pour moi (VS 2013) lorsque j'essayais de copier la dll de sortie d'un projet C ++ vers le dossier de publication et de débogage d'un autre projet C # dans la même solution.

J'ai dû ajouter l'action post-build suivante (clic droit sur le projet qui a une sortie .dll) puis propriétés -> propriétés de configuration -> événements de construction -> événement post-construction -> ligne de commande

maintenant j'ai ajouté ces deux lignes pour copier la dll de sortie dans les deux dossiers:

xcopy /y $(TargetPath) $(SolutionDir)aeiscontroller\bin\Release
xcopy /y $(TargetPath) $(SolutionDir)aeiscontroller\bin\Debug
SCBuergel.eth
la source
5

(Cette réponse s'applique uniquement à C # et non à C ++, désolé j'ai mal lu la question d'origine)

J'ai déjà traversé l'enfer des DLL comme ça. Ma solution finale était de stocker les DLL non gérées dans la DLL gérée en tant que ressources binaires, et de les extraire dans un dossier temporaire lorsque le programme se lance et de les supprimer lorsqu'il est supprimé.

Cela devrait faire partie de l'infrastructure .NET ou pinvoke, car c'est tellement utile ... Cela rend votre DLL gérée facile à gérer, à la fois en utilisant Xcopy ou en tant que référence de projet dans une solution Visual Studio plus grande. Une fois que vous faites cela, vous n'avez pas à vous soucier des événements post-build.

METTRE À JOUR:

J'ai posté le code ici dans une autre réponse https://stackoverflow.com/a/11038376/364818

Mark Lakata
la source
1
Je suis d'accord, cela devrait faire partie du cadre (pour lier statiquement les dll, etc.) - Il convient de noter que le stockage de la dll en tant que ressource puis son extraction au moment de l'exécution peut causer des problèmes dans certains environnements d'entreprise (surtout s'ils ont assez logiciel anti-virus proactif).
BrainSlugs83
1

Ajoutez une copie intégrée dans le fichier project.csproj :

  <Project>
    ...
    <Target Name="AfterBuild">
      <Copy SourceFiles="$(ProjectDir)..\..\Lib\*.dll" DestinationFolder="$(OutDir)Debug\bin" SkipUnchangedFiles="false" />
      <Copy SourceFiles="$(ProjectDir)..\..\Lib\*.dll" DestinationFolder="$(OutDir)Release\bin" SkipUnchangedFiles="false" />
    </Target>
  </Project>
John_J
la source
Il y a un bogue à long terme dans VS, veuillez utiliser ProjectDir plutôt que SolutionDir
John_J
0
xcopy /y /d  "$(ProjectDir)External\*.dll" "$(TargetDir)"

Vous pouvez également faire référence à un chemin relatif, l'exemple suivant trouvera la DLL dans un dossier situé un niveau au-dessus du dossier du projet. Si vous avez plusieurs projets qui utilisent la DLL dans une seule solution, cela place la source de la DLL dans une zone commune accessible lorsque vous définissez l'un d'entre eux comme projet de démarrage.

xcopy /y /d  "$(ProjectDir)..\External\*.dll" "$(TargetDir)"

L' /yoption copie sans confirmation. L' /doption vérifie si un fichier existe dans la cible et si elle ne copie que si la source a un horodatage plus récent que la cible.

J'ai trouvé que dans au moins les versions plus récentes de Visual Studio, telles que VS2109, $(ProjDir)n'est pas défini et devait être utilisé à la $(ProjectDir)place.

Laisser un dossier cible dans xcopydevrait par défaut le répertoire de sortie. C'est important pour comprendre que la raison $(OutDir)seule n'est pas utile.

$(OutDir), au moins dans les versions récentes de Visual Studio, est défini comme un chemin d'accès relatif au dossier de sortie, tel que bin/x86/Debug. L'utiliser seul comme cible créera un nouvel ensemble de dossiers à partir du dossier de sortie du projet. Ex: … bin/x86/Debug/bin/x86/Debug.

Le combiner avec le dossier du projet devrait vous amener au bon endroit. Ex: $(ProjectDir)$(OutDir).

Cependant $(TargetDir)fournira le répertoire de sortie en une seule étape.

Liste de Microsoft des macros MSBuild pour les versions actuelles et précédentes de Visual Studio

Shealer riche
la source