Ich habe vier Projekte in meiner Visual Studio-Lösung (alle, die auf .NET 3.5 abzielen) - für mein Problem sind nur diese beiden wichtig:
- MyBaseProject <- Diese Klassenbibliothek verweist auf eine DLL-Datei eines Drittanbieters (elmah.dll).
- MyWebProject1 <- Dieses Webanwendungsprojekt enthält einen Verweis auf MyBaseProject
Ich habe den Verweis elmah.dll zu MyBaseProject in Visual Studio 2008 hinzugefügt, indem ich auf "Verweis hinzufügen ..." → Registerkarte "Durchsuchen" → → "elmah.dll" ausgewählt habe.
Die Eigenschaften der Elmah-Referenz sind wie folgt:
- Aliase - global
- Lokal kopieren - wahr
- Kultur -
- Beschreibung - Fehlerprotokollierungsmodule und -handler (ELMAH) für ASP.NET
- Dateityp - Baugruppe
- Pfad - D: \ webs \ otherfolder \ _myPath \ __ tools \ elmah \ Elmah.dll
- Gelöst - Richtig
- Laufzeitversion - v2.0.50727
- Angegebene Version - falsch
- Starker Name - falsch
- Version - 1.0.11211.0
In MyWebProject1 habe ich den Verweis auf Project MyBaseProject hinzugefügt, indem ich: "Verweis hinzufügen ..." → Registerkarte "Projekte" → "MyBaseProject" ausgewählt habe. Die Eigenschaften dieser Referenz sind bis auf die folgenden Elemente identisch:
- Beschreibung -
- Pfad - D: \ webs \ CMS \ MyBaseProject \ bin \ Debug \ MyBaseProject.dll
- Version - 1.0.0.0
Wenn ich den Build in Visual Studio ausführe, wird die Datei elmah.dll zusammen mit MyBaseProject.dll in das bin- Verzeichnis von MyWebProject1 kopiert!
Wenn ich jedoch MSBuild für die Lösung bereinige und ausführe (über D: \ webs \ CMS> C: \ WINDOWS \ Microsoft.NET \ Framework \ v3.5 \ MSBuild.exe / t: ReBuild / p: Configuration = Debug MyProject.sln ) Die Datei elmah.dll fehlt im bin-Verzeichnis von MyWebProject1 - obwohl der Build selbst keine Warnungen oder Fehler enthält!
Ich habe bereits sichergestellt, dass die .csproj von MyBaseProject das private Element mit dem Wert "true" enthält (dies sollte ein Alias für " copy local " in Visual Studio sein):
<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>
(Das private Tag wurde standardmäßig nicht in der XML-Datei von .csproj angezeigt, obwohl Visual Studio "copy local" true sagte. Ich habe "copy local" auf "false" gesetzt - gespeichert - und es wieder auf "true" gesetzt - save!)
Was ist los mit MSBuild? Wie kann ich die Referenz (elmah.dll) in den Bin von MyWebProject1 kopieren lassen?
Ich möchte dem Postbuild-Befehl jedes Projekts KEINE Postbuild-Kopieraktion hinzufügen! (Stellen Sie sich vor, ich hätte viele Projekte, die von MyBaseProject abhängen!)
Antworten:
Ich bin nicht sicher, warum es beim Erstellen zwischen Visual Studio und MsBuild anders ist, aber hier ist, was ich gefunden habe, als ich auf dieses Problem in MsBuild und Visual Studio gestoßen bin.
Erläuterung
Nehmen wir für ein Beispielszenario an, wir haben Projekt X, Baugruppe A und Baugruppe B. Baugruppe A verweist auf Baugruppe B, sodass Projekt X einen Verweis auf A und B enthält. Außerdem enthält Projekt X Code, der auf Baugruppe A verweist (z. B. A. SomeFunction ()). Jetzt erstellen Sie ein neues Projekt Y, das auf Projekt X verweist.
Die Abhängigkeitskette sieht also folgendermaßen aus: Y => X => A => B.
Visual Studio / MSBuild versucht, intelligent zu sein und nur Referenzen in Projekt Y zu übertragen, die als von Projekt X erforderlich erkannt werden. Dies geschieht, um Referenzverschmutzung in Projekt Y zu vermeiden. Das Problem ist, dass VS / MSBuild nicht erkennt, dass B erforderlich ist, da Projekt X keinen Code enthält, der explizit Assembly B verwendet (z. B. B.SomeFunction ()) von X und kopiert es daher nicht in das bin-Verzeichnis von Projekt Y; Es werden nur die X- und A-Assemblys kopiert.
Lösung
Sie haben zwei Möglichkeiten, um dieses Problem zu lösen. Beide führen dazu, dass Baugruppe B in das bin-Verzeichnis von Projekt Y kopiert wird:
Persönlich bevorzuge ich Option 2 aus mehreren Gründen.
Hier ist ein Beispiel des "Dummy-Codes", den ich normalerweise hinzufüge, wenn ich auf diese Situation stoße.
quelle
Type dummyType = typeof(AssemblyA.AnyClass);
Console.WriteLine(dummyType.FullName);
enum
von B verwendete und davon ausging, dass die Aufzählung inline ist. Ich habe Code hinzugefügt, um einen Typ von B direkt zu verwenden, und das hat nicht geholfen. Es war auch immer so, dass mein X Typen in A verwendet, die Unterklassentypen in B sind, so dass ich nicht verstehen kann, wie der Compiler denkt, dass B von X nicht benötigt wird und ignoriert werden kann. Das sind Trottel.Ich gehe einfach so damit um. Gehen Sie zu den Eigenschaften Ihrer Referenz und gehen Sie folgendermaßen vor:
und das ist es.
In Visual Studio 2010 wird zunächst nicht Folgendes eingefügt:
<private>True</private>
Wenn Sie das Referenz-Tag in das Referenz-Tag setzen und "copy local" auf "false" setzen, wird das Tag erstellt. Danach wird es entsprechend auf wahr und falsch gesetzt.quelle
<Private>true</Private>
aber es schien keine Auswirkung auf MSBuild zu haben. Am Ende habe ich nur NuGet-Referenzen zu Downlevel-Projekten hinzugefügt.Have you tried turning it off and on again?
und es hat funktioniert!Wenn Sie die Assembly nicht direkt im Code verwenden, erkennt Visual Studio beim Versuch, hilfreich zu sein, dass sie nicht verwendet wird, und nimmt sie nicht in die Ausgabe auf. Ich bin nicht sicher, warum zwischen Visual Studio und MSBuild ein unterschiedliches Verhalten auftritt. Sie können versuchen, die Build-Ausgabe für beide auf Diagnose zu setzen und die Ergebnisse zu vergleichen, um festzustellen, wo sie abweichen.
Wenn Sie Ihre elmah.dll-Referenz nicht direkt im Code referenzieren, können Sie sie als Element zu Ihrem Projekt hinzufügen und die Build-Aktion auf
Content
und das Kopieren in Ausgabeverzeichnis auf setzenAlways
.quelle
Schauen Sie sich an:
Diesen MSBuild-Forenthread habe ich gestartet
Dort finden Sie meine vorübergehende Lösung / Problemumgehung!
(MyBaseProject benötigt Code, der auf einige Klassen (was auch immer) aus der elmah.dll verweist, damit elmah.dll in den Bin von MyWebProject1 kopiert wird!)
quelle
Ich hatte das gleiche Problem.
Überprüfen Sie, ob die Framework-Version Ihres Projekts mit der Framework-Version der DLL übereinstimmt, auf die Sie verweisen.
In meinem Fall wurde mein Client mit "Framework 4 Client" kompiliert und die DLL befand sich in "Framework 4".
quelle
Das Problem, mit dem ich konfrontiert war, war, dass ich ein Projekt habe, das von einem Bibliotheksprojekt abhängig ist. Um zu bauen, habe ich folgende Schritte ausgeführt:
Das bedeutete natürlich, dass mir die DLL-Dateien meiner Bibliothek in bin und vor allem in der Paket-Zip-Datei fehlten. Ich fand das funktioniert perfekt:
Ich habe keine Ahnung, warum diese Arbeit oder warum es überhaupt nicht funktioniert hat. Aber hoffe das hilft.
quelle
Ich hatte gerade genau das gleiche Problem und es stellte sich heraus, dass 2 Projekte in derselben Lösung auf eine andere Version der Bibliothek eines Drittanbieters verweisen.
Nachdem ich alle Referenzen korrigiert hatte, funktionierte alles perfekt.
quelle
Wie Alex Burtsev in einem Kommentar erwähnt hat, wird alles, was nur in einem XAML-Ressourcenwörterbuch verwendet wird, oder in meinem Fall alles, was nur in XAML und nicht in Code dahinter verwendet wird, von MSBuild nicht als "in Verwendung" angesehen.
Das einfache Neuerstellen eines Dummy-Verweises auf eine Klasse / Komponente in der Assembly in einem Code dahinter hat MSBuild davon überzeugt, dass die Assembly tatsächlich verwendet wird.
quelle
Ändern des Zielframeworks von .NET Framework 4-Clientprofil zu .NET Framework 4 dieses Problem für mich behoben.
In Ihrem Beispiel: Setzen Sie das Zielframework in MyWebProject1 auf .NET Framework 4
quelle
Mit dem Schema von Deaddog,
Y => X => A => B. ,
Mein Problem war, als ich Y erstellte, dass die Assemblys (A und B, alle 15) von X nicht im Ordner bin von Y angezeigt wurden.
Ich habe es gelöst, indem ich die Referenz X aus Y entfernt, gespeichert, erstellt, dann die X-Referenz (eine Projektreferenz) erneut hinzugefügt und gespeichert, erstellt habe und A und B im Ordner bin von Y angezeigt wurden.
quelle
Ich hatte das gleiche Problem und die DLL war eine dynamisch geladene Referenz. Um das Problem zu lösen, habe ich ein "using" mit dem Namespace der DLL hinzugefügt. Jetzt wird die DLL in den Ausgabeordner kopiert.
quelle
Dazu müssen Sie
.targets
Ihrem Projekt eine Datei hinzufügen und festlegen, dass sie in den Includes-Abschnitt des Projekts aufgenommen wird.Sehen meine Antwort hier für das Verfahren.
quelle
Das Referenzieren von Assemblys, die während des Builds nicht verwendet werden, ist nicht die richtige Vorgehensweise. Sie sollten Ihre Build-Datei erweitern, damit die zusätzlichen Dateien kopiert werden. Entweder mithilfe eines Post-Build-Ereignisses oder durch Aktualisieren der Eigenschaftsgruppe.
Einige Beispiele finden Sie in einem anderen Beitrag
quelle
Ein anderes Szenario, in dem dies angezeigt wird, ist, wenn Sie den älteren Projekttyp "Website" in Visual Studio verwenden. Für diesen Projekttyp kann es nicht auf DLLs verweisen, die sich außerhalb der eigenen Verzeichnisstruktur befinden (aktueller Ordner und nach unten). Nehmen wir in der obigen Antwort an, Ihre Verzeichnisstruktur sieht folgendermaßen aus:
Wenn ProjectX und ProjectY übergeordnete / untergeordnete Verzeichnisse sind und ProjectX auf A.dll verweist, die wiederum auf B.dll verweist, und B.dll außerhalb der Verzeichnisstruktur liegt, z. B. in einem Nuget-Paket im Stammverzeichnis (Packages), dann auf A. DLL wird enthalten sein, B. DLL jedoch nicht.
quelle
Ich hatte heute ein ähnliches Problem, und dies ist mit Sicherheit nicht die Antwort auf Ihre Frage. Aber ich möchte alle informieren und möglicherweise einen Funken Einsicht geben.
Ich habe eine ASP.NET-Anwendung. Der Erstellungsprozess wird auf Bereinigen und dann Erstellen festgelegt.
Ich habe zwei Jenkins CI- Skripte. Eine für die Produktion und eine für die Inszenierung. Ich habe meine Anwendung für das Staging bereitgestellt und alles hat einwandfrei funktioniert. Wird in der Produktion bereitgestellt und es fehlte eine DLL-Datei, auf die verwiesen wurde. Diese DLL-Datei befand sich nur im Stammverzeichnis des Projekts. Nicht in einem NuGet-Repository. Die DLL wurde auf gesetzt
do not copy
.Das CI-Skript und die Anwendung waren zwischen den beiden Bereitstellungen identisch. Nach dem Bereinigen und Bereitstellen in der Staging-Umgebung wurde die DLL-Datei am Bereitstellungsort der ASP.NET-Anwendung (
bin/
) ersetzt. Dies war in der Produktionsumgebung nicht der Fall.Es stellt sich heraus, dass ich in einem Testzweig dem Erstellungsprozess einen Schritt hinzugefügt habe, um diese DLL-Datei in die zu kopieren
bin
Verzeichnis . Nun der Teil, der eine Weile gedauert hat, um herauszufinden. Der CI-Prozess reinigte sich nicht von selbst. Die DLL wurde im Arbeitsverzeichnis belassen und versehentlich mit der ASP.NET-ZIP-Datei gepackt. Der Produktionszweig hatte die DLL-Datei nie auf die gleiche Weise kopiert und stellte diese niemals versehentlich bereit.TLDR; Überprüfen Sie, ob Sie wissen, was Ihr Build-Server tut.
quelle
Stellen Sie sicher, dass sich beide Projekte in derselben .net-Version befinden. Überprüfen Sie auch die lokale Eigenschaft zum Kopieren. Dies sollte jedoch
true
die Standardeinstellung seinquelle
Verwenden von Visual Studio 2015 Hinzufügen des zusätzlichen Parameters
In der msbuild-Befehlszeile wurde das Problem behoben.
quelle
Ich bin gerade auf ein sehr ähnliches Problem gestoßen. Beim Kompilieren mit Visual Studio 2010 wurde die DLL-Datei in den
bin
Ordner aufgenommen. Beim Kompilieren mit MSBuild wurde die DLL-Datei eines Drittanbieters jedoch nicht berücksichtigt.Sehr frustrierend. Die Art und Weise, wie ich es gelöst habe, bestand darin, den NuGet- Verweis auf das Paket in mein Webprojekt aufzunehmen, obwohl ich es dort nicht direkt verwende.
quelle
Das Einfügen aller referenzierten DLL-Dateien aus Ihren Projektreferenzen in das Website-Projekt ist nicht immer eine gute Idee, insbesondere wenn Sie die Abhängigkeitsinjektion verwenden : Ihr Webprojekt möchte lediglich einen Verweis auf die DLL-Datei / das Projekt der Schnittstelle hinzufügen, keine konkrete Implementierungs-DLL Datei.
Wenn Sie einen Verweis direkt auf eine Implementierungs-DLL-Datei / ein Implementierungs-DLL-Projekt hinzufügen, können Sie Ihren Entwickler nicht daran hindern, für konkrete Klassen der Implementierungs-DLL-Datei / des Implementierungs-DLL-Projekts ein "neues" aufzurufen, anstatt über die Schnittstelle. Außerdem haben Sie auf Ihrer Website einen "Hardcode" angegeben, um die Implementierung zu verwenden.
quelle