La DLL dipendente non viene copiata nella cartella di output di compilazione in Visual Studio

Ho una soluzione per lo studio visivo. Ho molti progetti nella soluzione. C’è un progetto principale che funge da avvio e utilizza altri progetti. C’è un progetto che dice “ProjectX”. Il suo riferimento è aggiunto al progetto principale. ProjectX fa riferimento a un’altra DLL .NET (ad esempio abc.dll) che non fa parte della soluzione.

Ora questo abc.dll dovrebbe essere copiato nella cartella bin / debug del progetto principale, ma non viene copiato lì. Perché non viene copiato, per qualsiasi motivo noto?

Ho scoperto che se ProjectX faceva riferimento a abc.dll ma non utilizzava direttamente nessuno dei tipi DEFINED in abc.dll, allora abc.dll NON verrebbe copiato nella cartella di output principale. (Verrebbe copiato nella cartella di output ProjectX, per renderlo più confuso.)

Quindi, se non si utilizza esplicitamente alcun tipo da abc.dll in qualsiasi parte in ProjectX, quindi inserire una dichiarazione fittizia da qualche parte in uno dei file in ProjectX.

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

Non è necessario farlo per ogni class: solo una volta sarà sufficiente per fare in modo che la DLL copi e tutto funzioni come previsto.

Addendum: si noti che questo potrebbe funzionare per la modalità di debug, ma NON per la versione. Vedi la risposta di @ nvirth per i dettagli.

Sì, dovrai impostare Copy Local su true . Tuttavia, sono abbastanza sicuro che dovrai anche fare riferimento a quell’assembly dal progetto principale e impostare Copy Local su true – non viene semplicemente copiato da un assembly dipendente.

È ansible accedere alla proprietà Copy Local facendo clic sull’assieme in References e premendo F4.

Solo un sidenote alla risposta di Overlord Zurg.

Ho aggiunto il riferimento fittizio in questo modo e ha funzionato in modalità debug:

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

Ma in modalità Release, la DLL dipendente non è stata ancora copiata.
Questo ha funzionato tuttavia:

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

Questa informazione mi è costata davvero ore per capire, quindi ho pensato di condividerlo.

Sembra shiny quando lo crei un attributo di assemblaggio

 [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 noop = _ => { }; noop(forcedType); } } 

L’utilizzo sarà:

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

Sono andato in questo stesso problema. Informazioni di base: prima di build, avevo aggiunto un nuovo progetto X alla soluzione. Il progetto Y dipendeva dal progetto X e il progetto A, B, C dipendeva dal progetto Y.

Gli errori di compilazione non consentivano la ricerca delle DLL dei progetti A, B, C, Y e X.

La causa principale era che il Progetto X appena creato aveva come target .NET 4.5 mentre il resto dei progetti della soluzione era stato progettato come .NET 4.5.1. Il progetto X non si è generato, causando la mancata creazione del resto dei progetti.

Assicurati che tutti i Progetti appena aggiunti abbiano come destinazione la stessa versione .NET del resto della soluzione.

Non sono sicuro se questo aiuta ma per me, molte volte faccio riferimento a una DLL (che automaticamente la aggiunge alla cartella bin ovviamente). Comunque quella DLL potrebbe aver bisogno di DLL aggiuntive (a seconda di quali funzioni sto usando). NON voglio fare riferimento a quelli del mio progetto perché semplicemente devono finire nella stessa cartella della DLL che sto effettivamente usando.

Lo realizzo in Visual Studio con “Aggiunta di un file esistente”. Dovresti essere in grado di aggiungerlo ovunque tranne la cartella Add_data. personalmente lo aggiungo alla radice.

Quindi modifica le proprietà di quel file in …

Build Action = None (con questo set su qualcosa come Content copia effettivamente la versione “root” nella root, più una copia nel Bin).

Copia nella cartella di output = Copia se più recente (in pratica lo inserisce nella cartella BIN solo se manca, ma non lo fa dopo)

Quando pubblico … la mia DLL aggiunta esiste solo nella cartella BIN e da nessun’altra parte nella locazione Pubblica (che è ciò che voglio).

Puoi anche verificare che le DLL che stai cercando non siano incluse nel GAC. Credo che Visual Studio stia facendo attenzione a non copiare quei file se già esiste nel GAC sulla macchina di compilazione.

Recentemente ho eseguito questa situazione in cui testavo un pacchetto SSIS che necessitava di assembly esistenti nel GAC. L’avevo dimenticato e mi chiedevo perché quelle DLL non uscissero durante una compilazione.

Per verificare cosa c’è nel GAC (da un prompt dei comandi di Visual Studio Developer):

 gacutil -l 

O uscita in un file per renderlo più facile da leggere:

 gacutil -l > output.txt notepad.exe output.txt 

Per rimuovere un assieme:

 gacutil -u MyProjectAssemblyName 

Dovrei anche notare, che una volta rimossi i file dal GAC, sono stati correttamente emessi nella directory \ bin dopo una build (anche per gli assembly che non erano referenziati direttamente nel progetto root). Questo era su Visual Studio 2013 Update 5.

Se hai ragione Fai clic sull’assieme di riferimento, vedrai una proprietà chiamata Copia locale . Se Copia locale è impostato su true, l’assembly deve essere incluso nel cestino. Tuttavia , ci sono problemi con Visual Studio, che a volte non include la dll di riferimento nella cartella bin … questa è la soluzione che ha funzionato per me:

inserisci la descrizione dell'immagine qui

Questa è una leggera modifica sull’esempio di nvirth

 internal class DummyClass { private static void Dummy() { Noop(typeof(AbcDll.AnyClass)); } private static void Noop(Type _) { } } 

È ansible impostare sia il progetto principale che il percorso di output di ProjectX nella stessa cartella, quindi è ansible ottenere tutte le DLL necessarie in quella cartella.

Assicurati che la DLL dipendente da te utilizzata non abbia un framework .net di destinazione superiore al framework .net target dell’applicazione del tuo progetto.

È ansible controllare questo selezionando il progetto, quindi premere ALT + INVIO, quindi selezionare Applicazione da sinistra e quindi selezionare Target Framework del progetto.

Supponiamo, dipendente dll Target Framework = 4.0 e Application dll Target Framework = 3.5 quindi cambiare questo a 4.0

Grazie!

Oltre a quelli comuni sopra, ho avuto una soluzione multi-progetto da pubblicare. Apparentemente alcuni file hanno come objective diversi framework.

Quindi la mia soluzione: Proprietà> Versione specifica (False)

NESSUN BISOGNO PER IL DUMMY IN CODICE
Appena :

aggiungere un riferimento al progetto eseguibile

o / e assicurarsi che il riferimento nel progetto eseguibile abbia "Copy Local" impostato su TRUE (che era il mio ” difetto “) sembra che questo “abbia sovrascritto” l’impostazione nel progetto di libreria di riferimento di base …

Aggiungi la DLL come elemento esistente a uno dei progetti e dovrebbe essere ordinata

Lo aggiungerei agli eventi Postbuild per copiare le librerie necessarie nelle directory di output. Qualcosa come XCopy pathtolibraries targetdirectory

Puoi trovarli sulle proprietà del progetto -> Crea eventi.

Nel mio caso, è stata la cosa più stupida, causata da un comportamento predefinito di TFS / VS con cui non sono d’accordo.

Poiché l’aggiunta della dll come riferimento al progetto principale non ha funzionato, ho deciso di aggiungerla come “Articolo esistente”, con Copia locale = Sempre. Anche allora il file non era lì.

Risulta che, anche se il file è presente sulla VS Solution e tutto è compilato sia localmente che sul server, VS / TFS non ha aggiunto effettivamente il file al controllo del codice sorgente. Non è stato incluso affatto nelle “Modifiche in sospeso”. Ho dovuto andare manualmente a Source Control Explorer e fare clic esplicitamente sull’icona “Aggiungi elementi alla cartella”.

Stupido perché ho sviluppato per 15 anni in VS. Mi sono imbattuto in questo prima, semplicemente non me lo ricordavo e in qualche modo mi mancava perché tutto era ancora compilato perché il file era un riferimento regolare, ma il file che era stato aggiunto come elemento esistente non veniva copiato perché non esisteva il server di controllo del codice sorgente.

Spero che questo salvi qualcuno da qualche tempo, dal momento che ho perso 2 giorni della mia vita a questo.