300 Stimmen

MSBuild kopiert keine Referenzen (DLL-Dateien), wenn Projektabhängigkeiten in der Lösung verwendet werden

Ich habe vier Projekte in meiner Visual Studio-Lösung (alle auf .NET 3.5 ausgerichtet) - für mein Problem sind nur diese beiden wichtig:

  1. MyBaseProject <- diese Klassenbibliothek verweist auf eine Drittanbieter-DLL-Datei (elmah.dll)
  2. MeinWebProjekt1 <- dieses Webanwendungsprojekt hat einen Verweis auf MyBaseProject

Ich habe den Verweis auf elmah.dll zu MyBaseProject in Visual Studio 2008 durch Klicken auf "Verweis hinzufügen..." Wählen Sie auf der Registerkarte "Durchsuchen" die Datei "elmah.dll" aus.

Die Eigenschaften der Elmah-Referenz sind wie folgt:

  • Aliasnamen - 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 - Wahr
  • Laufzeitversion - v2.0.50727
  • Angegebene Version - false
  • Starker Name - falsch
  • Version - 1.0.11211.0

MeinWebProjekt1 Ich habe den Verweis auf das Projekt MyBaseProject von hinzugefügt: "Referenz hinzufügen..." Registerkarte "Projekte", Auswahl von "MyBaseProject". Die Eigenschaften dieser Referenz sind die gleichen, mit Ausnahme der folgenden Mitglieder:

  • Beschreibung -
  • Pfad - D:\webs\CMS\MyBaseProject\bin\Debug\MyBaseProject.dll
  • Version - 1.0.0.0

Wenn ich den Build in Visual Studio Die Datei elmah.dll wird in mein MyWebProject1's Mülltonne Verzeichnis, zusammen mit MyBaseProject.dll!

Wenn ich jedoch sauber mache und MSBuild für die Lösung (über D:\webs\CMS > C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /t:ReBuild /p:Configuration=Debug MyProject.sln) die 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 die privat Element mit dem Wert "true" (das sollte ein Alias für " lokal kopieren " in Visual Studio):

<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 erschien standardmäßig nicht in der .csproj-xml, obwohl Visual Studio sagte, dass "copy local" true sei. Ich schaltete "copy local" auf false - gespeichert - und setzte es wieder auf true - gespeichert!)

Was ist mit MSBuild los? Wie bekomme ich die (elmah.dll) Referenz in MyWebProject1's bin kopiert?

Ich möchte NICHT zu jedem Postbuild-Befehl eines Projekts eine Kopieraktion hinzufügen! (Stellen Sie sich vor, ich hätte viele Projekte, die von MyBaseProject abhängen!)

173voto

deadlydog Punkte 20641

Ich bin nicht sicher, warum es beim Erstellen zwischen Visual Studio und MsBuild unterschiedlich ist, aber hier ist, was ich gefunden habe, wenn ich dieses Problem in MsBuild und Visual Studio aufgetreten ist.

説明

Nehmen wir an, wir haben ein Projekt X, eine Baugruppe A und eine Baugruppe B. Baugruppe A referenziert Baugruppe B, also enthält Projekt X einen Verweis auf A und B. Außerdem enthält Projekt X Code, der auf Baugruppe A verweist (z. B. A.SomeFunction()). Nun erstellen Sie ein neues Projekt Y, das auf Projekt X verweist.

Die Abhängigkeitskette sieht also wie folgt aus: Y => X => A => B

Visual Studio / MSBuild versucht, schlau zu sein und nur Verweise in Projekt Y zu bringen, die es als von Projekt X erforderlich erkennt; es tut dies, um Referenz Verschmutzung in Projekt Y zu vermeiden. Das Problem ist, da Projekt X eigentlich keinen Code enthält, der explizit Baugruppe B verwendet (z. B. B.SomeFunction()), VS/MSBuild erkennt nicht, dass B von X erforderlich ist, und kopiert es daher nicht in das Bin-Verzeichnis von Projekt Y; es kopiert nur die X und A Baugruppen.

Solución

Sie haben zwei Möglichkeiten, dieses Problem zu lösen, die beide dazu führen, dass Assembly B in das Bin-Verzeichnis von Projekt Y kopiert wird:

  1. Fügen Sie einen Verweis auf die Baugruppe B im Projekt Y hinzu.
  2. Fügen Sie Dummy-Code zu einer Datei in Projekt X hinzu, die Assembly B verwendet.

Ich persönlich bevorzuge Option 2 aus mehreren Gründen.

  1. Wenn Sie in Zukunft ein weiteres Projekt hinzufügen, das auf Projekt X verweist, müssen Sie nicht daran denken, auch einen Verweis auf Baugruppe B einzufügen (wie es bei Option 1 erforderlich wäre).
  2. Sie können in den Kommentaren ausdrücklich erklären, warum der Dummy-Code vorhanden sein muss und ihn nicht entfernen. Wenn also jemand den Code versehentlich löscht (z.B. mit einem Refactor-Tool, das nach unbenutztem Code sucht), können Sie in der Versionskontrolle leicht erkennen, dass der Code benötigt wird und ihn wiederherstellen. Wenn Sie Option 1 verwenden und jemand verwendet ein Refactor-Tool, um unbenutzte Referenzen zu bereinigen, haben Sie keine Kommentare; Sie sehen nur, dass eine Referenz aus der .csproj-Datei entfernt wurde.

Hier ist ein Beispiel für den "Dummy-Code", den ich in der Regel einfüge, wenn ich auf diese Situation treffe.

    // DO NOT DELETE THIS CODE UNLESS WE NO LONGER REQUIRE ASSEMBLY A!!!
    private void DummyFunctionToMakeSureReferencesGetCopiedProperly_DO_NOT_DELETE_THIS_CODE()
    {
        // Assembly A is used by this file, and that assembly depends on assembly B,
        // but this project does not have any code that explicitly references assembly B. Therefore, when another project references
        // this project, this project's assembly and the assembly A get copied to the project's bin directory, but not
        // assembly B. So in order to get the required assembly B copied over, we add some dummy code here (that never
        // gets called) that references assembly B; this will flag VS/MSBuild to copy the required assembly B over as well.
        var dummyType = typeof(B.SomeClass);
        Console.WriteLine(dummyType.FullName);
    }

173voto

andrew Punkte 2215

Ich gehe einfach so damit um. Gehen Sie zu den Eigenschaften Ihrer Referenz und tun Sie dies:

Set "Copy local = false"
Save
Set "Copy local = true"
Save

und das war's.

Visual Studio 2010 stellt zunächst nicht: <private>True</private> im Referenz-Tag und die Einstellung "copy local" auf false bewirkt, dass das Tag erstellt wird. Danach wird es entsprechend auf true und false gesetzt.

40voto

John Hunter Punkte 3942

Wenn Sie die Assembly nicht direkt im Code verwenden, erkennt Visual Studio zwar, dass sie nicht verwendet wird, nimmt sie aber nicht in die Ausgabe auf. Ich bin mir nicht sicher, warum Sie ein unterschiedliches Verhalten zwischen Visual Studio und MSBuild feststellen. Sie könnten versuchen, die Build-Ausgabe auf Diagnose für beide und vergleichen Sie die Ergebnisse sehen, wo es abweicht.

Wie für Ihre elmah.dll-Referenz, wenn Sie nicht direkt auf sie in Code verweisen, könnten Sie sie als Element zu Ihrem Projekt hinzufügen und die Build-Aktion auf Content und die Option In Ausgabeverzeichnis kopieren auf Always .

17voto

toebens Punkte 3929

Schauen Sie sich das an:

Dieser MSBuild-Forumsthread, den ich begonnen habe

Dort finden Sie meine vorläufige Lösung / Umgehung!

(MyBaseProject braucht einige Code, der einige Klassen (was auch immer) aus der elmah.dll für elmah.dll referenziert wird in MyWebProject1 bin kopiert!)

9voto

Andre Avelar Punkte 91

Ich hatte das gleiche Problem.

Prüfen Sie, ob die Framework-Version Ihres Projekts mit der Framework-Version der DLL übereinstimmt, die Sie als Referenz angeben.

In meinem Fall wurde mein Client mit "Framework 4 Client" kompiliert und die DLL war in "Framework 4".

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X