J'ai une solution de studio visuel ... J'ai plusieurs projets dans la solution ... Il y a un projet principal qui fait office de démarrage et utilise d'autres projets ... Il y a un projet dit "ProjectX". Sa référence est ajoutée au projet principal . ProjectX fait référence à une autre DLL .NET (par exemple, 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 ne sera pas copiée là-bas. Pourquoi n'est-il pas copié, pour des raisons connues?
J'ai constaté que si ProjectX faisait référence à abc.dll mais n'utilisait directement aucun des types DEFINED dans abc.dll, abc.dll ne serait PAS copié dans le dossier de sortie principal. (Il serait copié dans le dossier de sortie de ProjectX pour le rendre encore plus déroutant.)
Ainsi, si vous n'utilisez pas explicitement l'un des types d'abc.dll dans ProjectX, placez une déclaration fictive quelque part dans l'un des fichiers de 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 copie DLL et tout fonctionnent comme prévu.
Addendum: Notez que cela peut fonctionner pour le mode débogage, mais PAS pour la publication. Voir la réponse de @ nvirth pour plus de détails.
Juste une remarque à la réponse du suzerain Zurg.
J'ai ajouté la référence factice de cette façon et cela fonctionnait en mode débogage:
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.
Cela a cependant fonctionné:
public class DummyClass
{
private static void Dummy()
{
Action<Type> noop = _ => {};
var dummy = typeof(AbcDll.AnyClass);
noop(dummy);
}
}
Cette information m'a en fait coûté des heures à comprendre, alors je pensais la partager.
Oui, vous devrez définir Copy Local
sur true
. Cependant, je suis presque sûr vous aurez également besoin de référencer cette Assemblée à partir du projet principal et de définir également Copy Local
à true
- elle ne sera pas simplement copiée à partir d'une Assemblée dépendante.
Vous pouvez accéder à la propriété Copy Local
en cliquant sur l’assemblage sous References
et en appuyant sur F4.
Il semble lisse lorsque vous en faites un attribut Assembly
[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'utilisation sera:
[Assembly: ForceAssemblyReference(typeof(AbcDll.AnyClass))]
Couru dans ce 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 dll du projet A, B, C, Y et X étaient introuvables.
La cause première était que le projet X nouvellement créé ciblait .NET 4.5, tandis que les autres projets de solution ciblaient .NET 4.5.1. Le projet X n'a pas été construit, ce qui a empêché le reste des projets de se construire.
Assurez-vous que tous les projets récemment ajoutés ciblent la même version .NET que le reste de la solution.
Je ne suis pas sûr que cela aide, mais pour moi, je fais souvent référence à un DLL (qui l'ajoute automatiquement au dossier bin, bien sûr). Cependant, il est possible que DLL ait besoin de DLL supplémentaires (selon les fonctions que j'utilise). Je ne veux PAS faire référence à ceux de mon projet car ils doivent simplement se retrouver dans le même dossier que le DLL que j'utilise réellement.
J'accomplis cela dans Visual Studio en "ajoutant un fichier existant". Vous devriez pouvoir l'ajouter n'importe où sauf le dossier Add_data. Personnellement, je viens de l'ajouter à la racine.
Puis changez les propriétés de ce fichier en ...
Action de construction = Aucune (le fait que Content soit défini sur quelque chose comme Content copie en fait la version "racine" vers la racine, plus une copie dans le chutier).
Copier dans le dossier de sortie = Copier si plus récent (le place dans le dossier BIN uniquement s'il est manquant, mais ne le fait pas par la suite)
Quand je publie .. ma DLL ajoutée n'existe que dans le dossier BIN et nulle part ailleurs dans l'emplacement de publication (c'est ce que je veux).
Vous pouvez également vérifier que les DLL que vous recherchez ne sont pas incluses dans le GAC. Je pense que Visual Studio est intelligent pour ne pas copier ces fichiers s'il existe déjà dans le GAC sur la machine de génération.
J'ai récemment couru dans cette situation où j'avais testé un package SSIS qui nécessitait l'existence d'assemblages dans le GAC. Je l'avais oublié depuis et je me demandais pourquoi ces DLL ne sortaient pas lors de la compilation.
Pour vérifier le contenu du GAC (à partir d'une invite de commande de Visual Studio Developer):
gacutil -l
Ou exportez dans un fichier pour en faciliter la lecture:
gacutil -l > output.txt
notepad.exe output.txt
Pour retirer une assemblée:
gacutil -u MyProjectAssemblyName
Je dois aussi noter qu’une fois que j’ai supprimé les fichiers du GAC, ils ont été correctement affichés dans le répertoire\bin après une construction (même pour les assemblys qui n’étaient pas directement référencés dans le projet racine). C'était sur Visual Studio 2013 Update 5.
Ceci est un léger tweak sur l'exemple de nvirth
internal class DummyClass
{
private static void Dummy()
{
Noop(typeof(AbcDll.AnyClass));
}
private static void Noop(Type _) { }
}
Si vous cliquez avec le bouton droit de la souris sur l’assemblage référencé, vous verrez une propriété appelée Copier Local. Si Copy Local est défini sur true, l'assembly doit être inclus dans le bac. Cependant, il semble y avoir un problème avec Visual studio, qui n'inclut pas parfois la dll référencée dans le dossier bin ... voici la solution de contournement qui a fonctionné pour moi:
Vous pouvez définir à la fois le projet principal et le chemin de sortie de la génération de ProjectX dans le même dossier, puis vous pouvez obtenir toutes les dll dont vous avez besoin dans ce dossier.
Dans mon cas, c’était la chose la plus stupide, causée par un comportement par défaut de TFS/VS avec lequel je ne suis pas d’accord.
L'ajout de la DLL en tant que référence au projet principal n'ayant pas fonctionné, j'ai décidé de l'ajouter en tant qu '"élément existant", avec Copy Local = Always. Même alors le fichier n'était pas là.
Il s'avère que, même si le fichier est présent sur la solution VS et que tout a été compilé localement et sur le serveur, VS/TFS n'a pas ajouté le fichier au contrôle de source. Il n'a pas du tout été inclus dans les "modifications en attente". Je devais accéder manuellement à l'explorateur de contrôle de code source et cliquer explicitement sur l'icône "Ajouter des éléments au dossier".
Stupide parce que je développe depuis 15 ans en VS. Je me suis déjà heurté à cela, je ne m'en souvenais tout simplement pas et je l'avais manqué parce que tout était toujours compilé car le fichier était une référence régulière, mais le fichier ajouté en tant qu'article existant n'était pas copié car il n'existait pas le serveur de contrôle de source.
J'espère que cela fera gagner un peu de temps à quelqu'un, car j'ai perdu 2 jours de ma vie à cause de cela.
Problème:
Vous rencontrez un problème similaire pour un package NuGet DLL (Newtonsoft.json.dll) où la sortie de la génération n'inclut pas la DLL référencée. Mais la compilation se passe bien.
Réparer:
Parcourez vos projets dans un éditeur de texte et recherchez des références contenant des balises. Comme Vrai ou Faux. "Privé" est synonyme de "Copie locale". Quelque part dans les actions, MSBuild prend pour localiser les dépendances, il recherche votre dépendance ailleurs et décide de ne pas la copier.
Alors, parcourez chaque fichier .csproj/.vbproj et supprimez les balises manuellement. Reconstruisez et tout fonctionne à la fois dans Visual Studio et MSBuild. Une fois que cela fonctionne, vous pouvez revenir en arrière et mettre à jour le répertoire selon vos besoins.
Référence:
https://www.paraesthesia.com/archive/2008/02/13/what-to-do-ifo-copy-local-works-in-vs-but.aspx/
Assurez-vous que la DLL dépendante que vous utilisez n’a pas un framework .net cible supérieur au framework .net cible de l’application de votre projet.
Vous pouvez vérifier cela en sélectionnant votre projet, puis appuyez sur ALT + ENTRÉE, puis sélectionnez Application dans la partie gauche, puis sélectionnez Framework cible de votre projet.
Supposons, Dépendante Target Framework = 4.0 et Application Dll Target Framework = 3.5 puis changez cela en 4.0
Je vous remercie!
Outre les solutions communes ci-dessus, j'avais une solution multi-projets à publier. Apparemment, certains fichiers ciblent différents frameworks.
Donc ma solution: Propriétés> Version spécifique (False)
Ajoutez le DLL en tant qu'élément existant à l'un des projets et il devrait être trié
Je l'ajouterais aux événements Postbuild pour copier les bibliothèques nécessaires dans les répertoires de sortie. Quelque chose comme chemin cible de XCopy pathtolibraries
Vous pouvez les trouver sur les propriétés du projet -> Construire des événements.
PAS BESOIN DE DUMMY IN CODE
Juste :
ajouter une référence au projet exécutable
ou/et assurez-vous que la référence dans le projet exécutable a "Copy Local"
définie sur TRUE
(ce qui était mon "fault") semble que ce "écrasé" le paramètre du projet bibliothèque-référence référencé de base. .