239 votes

La DLL dépendante n'est pas copiée dans le dossier de sortie de la compilation dans Visual Studio.

J'ai une solution Visual Studio. J'ai plusieurs projets dans cette solution. Il y a un projet principal qui agit comme le démarrage et utilise d'autres projets. Il y a un projet appelé "ProjectX". Sa référence est ajoutée au projet principal. Le ProjectX fait référence à une autre dll .NET (disons abc.dll) qui ne fait pas partie de la solution.

Maintenant, cette abc.dll devrait être copiée dans le dossier bin/debug du projet principal, mais elle n'y est pas copiée. Pourquoi n'est-elle pas copiée, y a-t-il des raisons connues ?

2 votes

Si vous n'y arrivez pas, copiez-le dans votre pré-construction.

1 votes

Comment utilisez-vous votre "ProjetX" dans le projet principal - quel est le type de projet, la cible, etc.

2 votes

J'ai eu le même problème et cette réponse l'a résolu : stackoverflow.com/a/8213977/174469

130voto

Overlord Zurg Points 1872

J'ai découvert que si ProjectX faisait référence à abc.dll mais n'utilisait pas directement l'un des types DÉFINIS dans abc.dll, alors abc.dll ne serait PAS copié dans le dossier de sortie principal. (Elle serait copiée dans le dossier de sortie de ProjectX, pour rendre la situation encore plus confuse).

Ainsi, si vous n'utilisez pas explicitement un des types de abc.dll n'importe où dans ProjectX, alors mettez une déclaration factice quelque part dans un des fichiers dans ProjectX.

AbcDll.AnyClass dummy006; // this will be enough to cause the DLL to be copied

Vous n'avez pas besoin de faire cela pour chaque classe - une seule fois suffira pour que la DLL soit copiée et que tout fonctionne comme prévu.

Addendum : Notez que cela peut fonctionner en mode de débogage, mais PAS en mode de publication. Voir la réponse de @nvirth pour plus de détails.

12 votes

Cela ressemble à un piratage. L'ajout de la référence au projet principal semble suffisant.

3 votes

C'est un hack, mais comme nous l'a appris le CodeProject news d'aujourd'hui, même les compilateurs peuvent se tromper !

0 votes

L'ajout d'une référence dans le projet principal n'a pas fonctionné pour moi. Seul l'ajout de la référence factice a permis au compilateur de copier la dll référencée.

98voto

nvirth Points 650

Juste un aparté à la réponse de Overlord Zurg.

J'ai ajouté la référence fictive de cette façon, et cela a fonctionné en mode Debug :

public class DummyClass
{
    private static void Dummy()
    {
        var dummy = typeof(AbcDll.AnyClass);
    }
}

Mais en mode Release, la dll dépendante n'a toujours pas été copiée.
Mais cela a fonctionné :

public class DummyClass
{
    private static void Dummy()
    {
        Action<Type> noop = _ => {};
        var dummy = typeof(AbcDll.AnyClass);
        noop(dummy);
    }
}

Cette information m'a coûté des heures de recherche, alors j'ai pensé la partager.

9 votes

En mode release, l'optimiseur suppose que "dummy" n'est pas utilisé, cette ligne est donc inutile et doit être supprimée. mais lorsque vous utilisez "dummy" dans le code, l'optimiseur ne suppose pas que ce n'est pas nécessaire.

2 votes

La méthode ne fonctionne pas pour moi. AbcDll.AnyClass n'est toujours pas copié dans l'autre projet.

4 votes

Assurez-vous que AbcDll.AnyClass est utilisé comme champ ou propriété publique dans une classe publique, cela fonctionnera. Si vous l'utilisez dans le corps d'une méthode comme celle-ci, le compilateur ne le voir . Cela retardera le chargement de l'assemblage, ce qui n'est pas ce que vous souhaitez.

64voto

Michael Perrenoud Points 37869

Oui, vous devez définir Copy Local à true . Cependant, Je suis presque sûr vous devrez également faire référence à cet assemblage à partir du projet principal et définir Copy Local à true aussi - il n'est pas simplement copié d'un assemblage dépendant.

Vous pouvez vous rendre au Copy Local en cliquant sur l'assemblage sous References et en appuyant sur F4.

3 votes

@Brij, l'assemblage est-il référencé dans le fichier projet principal vous le voulez ? Comme je l'ai dit, Je suis presque sûr que vous devez également faire référence à ce projet - les assemblages dépendants ne sont pas copiés de cette manière. Si c'était le cas, vous n'auriez pas besoin d'ajouter les assemblages à tous les projets concernés lorsque vous utilisez NuGet.

1 votes

J'ai créé un exemple de solution dans Visual Studio. Dans cette solution, la dll dépendante est copiée dans le projet principal.

1 votes

@Brij, quelle est la différence entre les deux solutions ? Faites-vous référence à l'assemblage extérieur exactement de la même manière que dans l'autre solution ?

40voto

Arie R Points 476

Ça a l'air bien quand on en fait un attribut d'assemblage.

[AttributeUsage(AttributeTargets.Assembly)]
public class ForceAssemblyReference: Attribute
{        
    public ForceAssemblyReference(Type forcedType)
    {
        //not sure if these two lines are required since 
        //the type is passed to constructor as parameter, 
        //thus effectively being used
        Action<Type> noop = _ => { };
        noop(forcedType);
    }
}

L'usage sera :

[assembly: ForceAssemblyReference(typeof(AbcDll.AnyClass))]

0 votes

Merci, mais pour moi, cela ne fonctionne que lorsque j'ajoute l'attribut assembly à la dépendance (Project X), qui fait déjà référence à AbcDll.AnyClass. Et ensuite, cela ne fait rien de plus que normalement, où il copie l'AbcDll dans le répertoire de sortie de la dépendance. Il ne la copie toujours pas dans le répertoire de sortie du projet dépendant principal. Et je ne peux pas ajouter l'attribut à l'assemblage dépendant à moins d'ajouter également une référence à AbcDll. Lorsque je fais cela, AbcDll est déjà copié sans l'attribut.

30voto

Darren Alfonso Points 794

J'ai rencontré le même problème. Informations de base : avant la construction, j'avais ajouté un nouveau projet X à la solution. Le projet Y dépendait du projet X et les projets A, B, C dépendaient du projet Y.

Les erreurs de construction étaient que les dlls des projets A, B, C, Y et X ne pouvaient pas être trouvées.

La cause fondamentale était que le projet X nouvellement créé ciblait .NET 4.5 alors que le reste des projets de la solution ciblait .NET 4.5.1. Le projet X ne s'est pas construit, entraînant le reste des projets à ne pas se construire non plus.

Assurez-vous que tous les projets nouvellement ajoutés ciblent la même version .NET que le reste de la solution.

1 votes

Les projets référencés peuvent être une ancienne version de .NET. Je peux référencer un projet construit pour .NET 4 par un projet construit pour .NET 4.5.

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