293 votes

MSBuild ne ' t copie référence (dll) si vous utilisez des dépendances de projet dans une solution

j'ai eu un coup d'oeil sur beaucoup de questions similaires sur ce côté, mais aucun d'eux n'a répondu à la question à mon problème. Toute la journée j'ai essayé de résoudre ce problème en vue de trouver une solution (via google etc.):

J'ai 4 projets dans ma VS solution (tout le monde de ciblage .net 3.5) - pour mon problème de seulement ces deux sont importants:

  1. MyBaseProject <- cette bibliothèque de classe fait référence à une 3ème partie de la dll (elmah.dll)
  2. MyWebProject1 <- ce projet d'application web a une référence à MyBaseProject

J'ai ajouté de l'elmah.dll référence à MyBaseProject dans Visual studio 2008 en cliquant sur "Ajouter une référence..." - > onglet "Parcourir" - > sélection de la "elmah.dll".

Les Propriétés de la Elmah de Référence sont comme suit:

  • Alias - global
  • Copie locale - vrai
  • Culture -
  • Description de Modules d'enregistrement des Erreurs et des Gestionnaires (en apparence) pour ASP.NET
  • Type De Fichier - Assemblée
  • Le Chemin D'Accès D:\webs\otherfolder\_myPath\__tools\elmah\Elmah.dll
  • Résolu - Vrai
  • D'exécution de la version v2.0.50727
  • Version - faux
  • Nom fort - faux
  • Version - 1.0.11211.0

Dans MyWebProject1 j'ai ajouté la référence au Projet MyBaseProject par: "Ajouter une référence..." - > onglet "Projets" - > sélection de la "MyBaseProject". Les Propriétés de cette référence sont les mêmes, sauf les membres suivants:

  • Description -
  • Le Chemin D'Accès D:\webs\CMS\MyBaseProject\bin\Debug\MyBaseProject.dll
  • La Version 1.0.0.0

Si je lance le construire dans visual studio l'elmah.dll est copié sur mon MyWebProject1 bin du répertoire, ainsi que de MyBaseProject.dll!

Cependant si j'ai nettoyer et exécuter msbuild pour la solution (via D:\webs\CMS>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /t:Reconstruire /p:Configuration=Debug MyProject.sln) l' elmah.dll est manquant dans MyWebProject1 répertoire bin - bien que le construire lui-même ne contient pas d'erreurs ou d'avertissement!

Je l'ai déjà fait en sorte que l' .csproj de MyBaseProject contient le privé élément avec la valeur "true" (qui devrait être un alias de "copie locale" dans VS):

<Reference Include="Elmah, Version=1.0.11211.0, Culture=neutral, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>..\mypath\__tools\elmah\Elmah.dll</HintPath>
    **<Private>true</Private>**
</Reference>

(Le privé balise ne figure pas dans la .csproj xml par défaut, bien que VS dit "copie locale" vrai. Je suis passé de "copie locale" faux - sauvé - et la définir à vrai nouveau - sauver!!!)

Quel est le problème avec MSBUILD? Comment faire pour obtenir l' (elmah.dll référence copié à MyWebProject1 bin?

Je ne veux PAS ajouter un postbuild copie d'action à tous les projets postbuild commande! (Imaginez que j'aurais beaucoup de projets dépendent de MyBaseProject!)

171voto

andrew Points 965

J’ai juste traiter comme ça. Allez dans les propriétés de votre référence et pour ce faire :

et c’est tout.

Visual Studio 2010 ne met pas au départ : `` dans la référence de tag et la définition de « copie locale » false provoque qu’il crée la balise. Par la suite il va le mettre à true et false en conséquence.

169voto

deadlydog Points 1840

Je ne suis pas sûr pourquoi elle est différente lors de la construction entre Visual Studio et MsBuild, mais voici ce que j'ai trouvé lorsque j'ai rencontré ce problème dans MsBuild et Visual Studio.

Explication

Pour un exemple de scénario disons que nous avons le projet X, l'assemblage et le montage B. Assemblée Une des références de l'assemblée B, de sorte que le projet X inclut une référence à la fois à A et B. en outre, le projet X inclut le code qui fait référence à l'assemblage (par exemple, A. SomeFunction()). Maintenant, vous créez un nouveau projet de qui Y des références de projet X.

Si la dépendance de la chaîne d'ressemble à ceci: Y => X => A => B

Visual Studio / MSBuild essaie d'être intelligent, et seulement apporter des références sur le projet Y qu'il détecte comme étant nécessaire par le projet X; il fait cela pour éviter de référence de la pollution dans le projet Y. Le problème est que, depuis que le projet X ne contiennent pas de code qui utilise explicitement montage B (par exemple, B. SomeFunction()), VS/MSBuild ne détecte pas que B est requis par X, et donc de ne pas la copier dans le projet Y est bin; il ne copie que les X et les assemblages.

Solution

Vous avez deux options pour résoudre ce problème, qui aura pour résultat l'assemblée B en cours de copie sur le projet Y est bin:

  1. Ajouter une référence à l'assembly B dans le projet Y.
  2. Ajouter mannequin code dans un fichier de projet X, qui utilise l'assemblée B.

Personnellement, je préfère l'option 2 pour un couple de raisons.

  1. Si vous ajoutez un autre projet dans l'avenir que les références de projet X, vous n'aurez pas à se rappeler d'inclure une référence à l'assembly B (comme vous auriez à le faire avec l'option 1).
  2. Vous pouvez avoir des commentaires explicites de dire pourquoi le code factice doit être là et de ne pas le supprimer. Donc si quelqu'un à supprimer le code par accident (avec un peu de remaniement outil de recherche de code inutilisé), vous pouvez facilement voir à partir de la source de contrôle que le code est nécessaire et de le restaurer. Si vous utilisez l'option 1 et que quelqu'un utilise un refactoriser outil pour nettoyer les références inutiles, vous n'avez pas de commentaires; vous allez voir que la référence a été retiré de la .fichier csproj.

Voici un exemple de "mannequin de code" que j'ai ajouter généralement quand je rencontre cette situation.

    // DO NOT DELETE THIS CODE UNLESS WE NO LONGER REQUIRE ASSEMBLY A!!!
    private void DummyFunctionToMakeSureReferencesGetCopiedProperly_DO_NOT_DELETE_THIS_CODE()
    {
        // Assembly A is used by this file, and that assembly depends on assembly B,
        // but this project does not have any code that explicitly references assembly B. Therefore, when another project references
        // this project, this project's assembly and the assembly A get copied to the project's bin directory, but not
        // assembly B. So in order to get the required assembly B copied over, we add some dummy code here (that never
        // gets called) that references assembly B; this will flag VS/MSBuild to copy the required assembly B over as well.
        var dummy = new B.SomeClassOrFunction();
    }

40voto

John Hunter Points 2204

Si vous n'êtes pas à l'aide de l'assemblée directement dans le code visual studio, tout en essayant d'être utile détecte qu'il n'est pas utilisé et ne pas l'inclure dans la sortie. Je ne suis pas sûr pourquoi vous voyez des différences de comportement entre visual studio et msbuild. Vous pouvez essayer le réglage de la sortie de la construction de diagnostic pour les deux et de comparer les résultats voir où ça diverge.

Comme pour votre elmah.dll référence si vous n'êtes pas référence directement dans le code, vous pourriez ajouter un élément à votre projet et de définir l'Action de génération de Contenu et le Copier vers le Répertoire de Sortie pour Toujours.

17voto

toebens Points 879

Jetez un oeil à :

Ce fil de forum msbuild que j’ai commencé

vous y trouverez ma solution temporaire / solution là !

(MyBaseProject a besoin d’un code qui fait référence à certaines classes (quoi que) de la elmah.dll pour elmah.dll soit copié dans bin de MyWebProject1 !)

9voto

Andre Avelar Points 51

J’ai eu le même problème.

Vérifiez si la version du framework de votre projet est celle de la version du framework de la dll que vous mettez sur la référence.

Dans mon cas, mon client a été compilé à l’aide de « Framework 4 Client » et la DLL a été dans « cadre 4".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X