wake-up-neo.com

Abhängig DLL wird nicht in den Build-Ausgabeordner in Visual Studio kopiert

Ich habe eine visuelle Studiolösung . Ich habe viele Projekte in der Lösung . Es gibt ein Hauptprojekt, das als Startup dient und andere Projekte verwendet . Es gibt ein Projekt, das "ProjectX" sagt. Seine Referenz wird zum Hauptprojekt hinzugefügt. Das ProjectX verweist auf eine andere .NET-DLL (z. B. abc.dll), die nicht Teil der Lösung ist. 

Jetzt sollte diese abc.dll in den bin/debug-Ordner des Hauptprojekts kopiert werden, aber es wird dort nicht kopiert. Warum wird es nicht aus bekannten Gründen kopiert?

148
Brij

Ich fand, dass, wenn ProjectX auf die abc.dll verwies, aber keinen der Typen DEFINED in abc.dll direkt verwendete, abc.dll NICHT in den Hauptausgabeordner kopiert würde. (Es wird in den ProjectX-Ausgabeordner kopiert, um es besonders verwirrend zu machen.)

Wenn Sie also keinen der Typen aus abc.dll irgendwo in ProjectX verwenden, fügen Sie eine Dummy-Deklaration irgendwo in eine der Dateien in ProjectX ein.

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

Sie müssen dies nicht für jede Klasse tun - nur einmal genügt, um die DLL - Kopie zu erstellen und alles wie erwartet zu funktionieren.

Nachtrag: Beachten Sie, dass dies für den Debug-Modus funktionieren kann, NICHT aber für die Veröffentlichung. Weitere Informationen finden Sie in der Antwort von @nvirth.

95
Overlord Zurg

Nur eine Randbemerkung zu Overlord Zurgs Antwort.

Ich habe den Dummy-Verweis auf diese Weise hinzugefügt und im Debug-Modus funktioniert:

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

Im Freigabemodus wurde die abhängige DLL jedoch immer noch nicht kopiert. 
Dies funktionierte jedoch:

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

Diese Informationen haben mich tatsächlich Stunden gekostet, um es herauszufinden, also dachte ich, ich teile es mit.

47
nvirth

Ja, Sie müssen Copy Local auf true setzen. Ich bin mir ziemlich sicher Sie müssen diese Assembly auch aus dem Hauptprojekt referenzieren und Copy Local auf true setzen - es wird nicht nur von einer abhängigen Assembly kopiert.

Sie können zur Eigenschaft Copy Local gelangen, indem Sie unter References auf die Assembly klicken und F4 drücken.

47
Mike Perrenoud

Es sieht glatt aus, wenn Sie es zu einem Assembly-Attribut machen

[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);
    }
}

Die Verwendung wird sein:

[Assembly: ForceAssemblyReference(typeof(AbcDll.AnyClass))]
25
Arie R

Ich bin in dieselbe Ausgabe geraten. Hintergrundinfo: Vor dem Bauen hatte ich der Lösung ein neues Projekt X hinzugefügt. Projekt Y war abhängig von Projekt X und Projekt A, B, C abhängig von Projekt Y.

Build-Fehler waren, dass die Projekt-A-, B-, C-, Y- und X-DLLs nicht gefunden werden konnten.

Die Hauptursache war, dass das neu erstellte Project X .NET 4.5 ansprach, während der Rest der Lösungsprojekte .NET 4.5.1 anvisierte. Project X wurde nicht erstellt, sodass auch die restlichen Projekte nicht erstellt wurden.

Stellen Sie sicher, dass alle neu hinzugefügten Projekte auf die gleiche .NET-Version abzielen wie der Rest der Lösung.

18
Darren Alfonso

Nicht sicher, ob dies hilft, aber für mich verweise ich oft auf eine DLL (die sie automatisch zum Ordner bin hinzufügt). Allerdings benötigt DLL möglicherweise zusätzliche DLLs (abhängig von den verwendeten Funktionen). Ich möchte NICHT auf diejenigen in meinem Projekt verweisen, da diese einfach im selben Ordner wie das von mir verwendete DLL enden müssen.

Ich verwende dies in Visual Studio durch "Hinzufügen einer vorhandenen Datei". Sie sollten es an einer beliebigen Stelle außer dem Ordner Add_data hinzufügen können. Ich persönlich füge es einfach zur Wurzel hinzu.

Ändern Sie dann die Eigenschaften dieser Datei in ...

Build-Aktion = Keine (wenn diese Einstellung auf "Inhalt" gesetzt ist, wird die "root" -Version in das Stammverzeichnis kopiert, plus eine Kopie in der Bin).

Kopieren in den Ausgabeordner = Kopieren, wenn neuer (legt es grundsätzlich nur im BIN-Ordner ab, wenn es fehlt, macht es danach aber nicht)

Wenn ich publiziere, existieren meine hinzugefügten DLLs nur im BIN-Ordner und sonst nirgendwo im Veröffentlichungsverzeichnis (was ich will).

15
da_jokker

Sie können auch überprüfen, ob die von Ihnen gesuchten DLLs nicht im GAC enthalten sind. Ich bin der Meinung, dass Visual Studio klug ist, diese Dateien nicht zu kopieren, wenn sie bereits im GAC auf der Buildmaschine vorhanden sind.

Ich war vor kurzem in einer Situation, in der ich ein SSIS-Paket getestet hatte, für das Baugruppen im GAC vorhanden sein mussten. Ich hatte das vergessen und wunderte mich, warum diese DLLs während eines Builds nicht herauskamen.

So überprüfen Sie den Inhalt des GAC (über eine Eingabeaufforderung von Visual Studio Developer):

gacutil -l

Oder in eine Datei ausgeben, um das Lesen zu erleichtern:

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

So entfernen Sie eine Baugruppe:

gacutil -u MyProjectAssemblyName

Ich sollte auch beachten, dass sobald ich die Dateien aus dem GAC entfernte, diese nach einem Build korrekt im\bin-Verzeichnis ausgegeben wurden (auch für Assemblys, die nicht direkt im Stammprojekt referenziert wurden). Dies war auf Visual Studio 2013 Update 5.

10
Brett

Dies ist ein kleiner Tweak am Beispiel von nvirth

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

Wenn Sie mit der rechten Maustaste auf die referenzierte Assembly klicken, wird eine Eigenschaft mit dem Namen Copy Local angezeigt. Wenn "Copy Local" auf "true" gesetzt ist, sollte die Assembly in der Bin enthalten sein. Allerdings, es scheint ein Problem mit Visual Studio zu geben, dass manchmal die referenzierte DLL nicht im Ordner bin enthalten ist.

 enter image description here

1
Hooman Bahreini

Sie können sowohl das Hauptprojekt als auch den Build-Ausgabepfad von ProjectX auf denselben Ordner festlegen. Anschließend können Sie alle erforderlichen DLLs in diesem Ordner abrufen.

0
YantingChen

In meinem Fall war es das Dümmste, verursacht durch ein Standardverhalten von TFS/VS, dem ich nicht zustimme.

Da das Hinzufügen der DLL als Referenz zum Hauptprojekt nicht funktionierte, entschied ich mich, sie als "Vorhandenes Element" mit Copy Local = Always hinzuzufügen. Selbst dann war die Akte nicht da.

Es stellt sich heraus, dass VS/TFS die Datei zwar nicht in der Quellcodeverwaltung hinzugefügt hat, obwohl die Datei in der VS Solution vorhanden ist und alles lokal und auf dem Server kompiliert wurde. Es war überhaupt nicht in den "Pending Changes" enthalten. Ich musste manuell zum Source Control Explorer gehen und explizit auf das Symbol "Elemente zum Ordner hinzufügen" klicken.

Blöd, weil ich mich seit 15 Jahren in VS entwickle. Ich bin schon einmal darauf gestoßen, ich habe mich einfach nicht erinnert und irgendwie habe ich es vermisst, weil alles noch kompiliert wurde, weil die Datei eine reguläre Referenz ist, aber die als Vorhandenes Objekt hinzugefügte Datei wurde nicht kopiert, weil sie nicht vorhanden war der Quellcodeverwaltungsserver.

Ich hoffe, dass dies jemandem etwas Zeit erspart, da ich 2 Tage meines Lebens daran verloren habe.

0
GR7

Problem:

Bei einem NuGet-Paket DLL (Newtonsoft.json.dll) ist ein ähnliches Problem aufgetreten, bei dem die Build-Ausgabe die referenzierte DLL nicht enthält. Aber die Zusammenstellung geht gut durch.

Fix:

Durchsuchen Sie Ihre Projekte in einem Texteditor und suchen Sie nach Referenzen mit Tags. Wie wahr oder falsch. "Privat" ist ein Synonym für "Lokal kopieren". Irgendwo in den Aktionen sucht MSBuild nach Abhängigkeiten, findet Ihre Abhängigkeit woanders und entscheidet, sie nicht zu kopieren.

Gehen Sie also jede .csproj/.vbproj-Datei durch und entfernen Sie die Tags manuell. Neu erstellen und alles funktioniert sowohl in Visual Studio als auch in MSBuild. Sobald Sie das erledigt haben, können Sie zurückkehren und das Update dahin bringen, wo Sie glauben, dass es sein muss.

Referenz:

https://www.paraesthesia.com/archive/2008/02/13/what-to-do-if-copy-local-works-in-vs-but.aspx/

0
Nkl Kumar

Stellen Sie sicher, dass die von Ihnen verwendete abhängige DLL nicht über das Ziel-.net-Framework verfügt, das höher ist als das Ziel-.net-Framework der Anwendung Ihres Projekts.

Sie können dies überprüfen, indem Sie Ihr Projekt auswählen, ALT + EINGABETASTE drücken, dann auf der linken Seite Anwendung auswählen und dann Ziel-Framework Ihres Projekts auswählen.

Angenommen, Abhängiges dll Target Framework = 4.0 und Anwendungs-DLL-Target-Framework = 3.5, dann ändern Sie dies auf 4.0

Vielen Dank!

0
Manish Jain

Abgesehen von den oben genannten hatte ich eine Multiprojektlösung, die veröffentlicht werden konnte. Anscheinend zielen einige Dateien auf andere Frameworks ab.

Also meine Lösung: Eigenschaften> Spezifische Version (False)

0
RicL

Fügen Sie das DLL als ein vorhandenes Element zu einem der Projekte hinzu und es sollte sortiert werden

0
abhijithkarkal

Ich würde es zu Postbuild-Ereignissen hinzufügen, um notwendige Bibliotheken in die Ausgabeverzeichnisse zu kopieren. So etwas wie XCopy-Pfadverzeichnisbibliotheken

Sie finden sie unter Projekteigenschaften -> Ereignisse erstellen.

0
chethan jain

KEINE NOTWENDIGKEIT FÜR DUMMY IM CODE
Gerade :

fügen Sie dem ausführbaren Projekt eine Referenz hinzu

oder/und sicherstellen, dass für den Verweis im ausführbaren Projekt "Copy Local" auf TRUE gesetzt wurde (was mein "fault" war), scheint diese "überschreibe" die Einstellung im Basis-Bibliotheksprojekt. .

0
Cadburry