Ich habe eine ähnliche Situation mit externen und internen Paketquellen mit Projekten, auf die in mehr als einer Lösung verwiesen wird. Ich habe dies heute mit einer unserer Codebasen zum Laufen gebracht und es scheint mit den Entwickler-Workstations und unserem Build-Server zu funktionieren. Der folgende Prozess berücksichtigt dieses Szenario (obwohl es nicht schwierig sein sollte, den allgemeinen Paketordner an einem anderen Ort anzupassen).
- Codebasis
- Projekt A.
- Projekt B.
- Projekt C.
- Lösungen
- Lösung 1
- Lösung 2
- Lösung 3
- Pakete (dies ist das gemeinsame Paket, das von allen Lösungen gemeinsam genutzt wird)
Aktualisierte Antwort ab NuGet 3.5.0.1484 mit Visual Studio 2015 Update 3
Dieser Prozess ist jetzt etwas einfacher als damals, als ich dies ursprünglich in Angriff genommen habe und dachte, es sei Zeit, dies zu aktualisieren. Im Allgemeinen ist der Prozess der gleiche, nur mit weniger Schritten. Das Ergebnis ist ein Prozess, der Folgendes löst oder bereitstellt:
- Alles, was für die Quellcodeverwaltung festgeschrieben werden muss, ist in der Lösung sichtbar und wird nachverfolgt
- Beim Installieren neuer Pakete oder Aktualisieren von Paketen mithilfe des Paketmanagers in Visual Studio wird der richtige Repository-Pfad verwendet
- Nach der Erstkonfiguration kein Hacken von .csproj-Dateien
- Keine Änderungen an der Entwickler-Workstation (Code wird beim Auschecken erstellt)
Es gibt einige mögliche Nachteile, die zu beachten sind (ich habe sie noch nicht erlebt, YMMV). Siehe Benols Antwort und Kommentare unten.
Fügen Sie NuGet.Config hinzu
Sie möchten eine NuGet.Config-Datei im Stammverzeichnis des Ordners \ Solutions \ erstellen. Stellen Sie sicher, dass es sich um eine UTF-8-codierte Datei handelt, die Sie erstellen. Wenn Sie sich nicht sicher sind, wie Sie dies tun sollen, verwenden Sie das Menü Datei-> Neu-> Datei von Visual Studio und wählen Sie dann die XML-Dateivorlage aus. Fügen Sie NuGet.Config Folgendes hinzu:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="$\..\Packages" />
</config>
</configuration>
Für die Einstellung repositoryPath können Sie mit dem Token $ einen absoluten Pfad oder einen relativen Pfad (empfohlen) angeben. Das $ -Token basiert darauf, wo sich die NuGet.Config befindet (Das $ -Token bezieht sich tatsächlich auf eine Ebene unterhalb der Position der NuGet.Config). Wenn ich also \ Solutions \ NuGet.Config habe und \ Solutions \ Packages möchte, muss ich $ \ .. \ Packages als Wert angeben.
Als Nächstes möchten Sie Ihrer Lösung einen Lösungsordner mit dem Namen "NuGet" hinzufügen (Klicken Sie mit der rechten Maustaste auf Ihre Lösung, Hinzufügen-> Neuer Lösungsordner). Lösungsordner sind virtuelle Ordner, die nur in der Visual Studio-Lösung vorhanden sind und keinen tatsächlichen Ordner auf dem Laufwerk erstellen (und Sie können von überall auf Dateien verweisen). Klicken Sie mit der rechten Maustaste auf Ihren "NuGet" -Lösungsordner und dann auf Hinzufügen-> Vorhandenes Element und wählen Sie \ Solutions \ NuGet.Config.
Der Grund, warum wir dies tun, ist, dass es in der Lösung sichtbar ist und dabei helfen soll, sicherzustellen, dass es ordnungsgemäß für Ihre Quellcodeverwaltung verwendet wird. Möglicherweise möchten Sie diesen Schritt für jede Lösung in Ihrer Codebasis ausführen, die an Ihren freigegebenen Projekten teilnimmt.
Indem wir die NuGet.Config-Datei in \ Solutions \ über alle .sln-Dateien platzieren, nutzen wir die Tatsache, dass NuGet rekursiv aus dem "aktuellen Arbeitsverzeichnis" in der Ordnerstruktur nach oben navigiert und nach einer zu verwendenden NuGet.Config-Datei sucht. Das "aktuelle Arbeitsverzeichnis" bedeutet hier ein paar verschiedene Dinge, einer ist der Ausführungspfad von NuGet.exe und der andere ist der Speicherort der SLN-Datei.
Umschalten Ihres Paketordners
Zunächst empfehle ich dringend, dass Sie jeden Ihrer Lösungsordner durchsuchen und alle vorhandenen \ Packages \ -Ordner löschen (Sie müssen zuerst Visual Studio schließen). Auf diese Weise können Sie leichter erkennen, wo NuGet Ihren neu konfigurierten Ordner \ Packages \ ablegt, und sicherstellen, dass alle Links zu falschen Ordnern \ Packages \ fehlschlagen und dann behoben werden können.
Öffnen Sie Ihre Lösung in Visual Studio und starten Sie ein Rebuild All. Ignorieren Sie alle Build-Fehler, die Sie erhalten. Dies wird an dieser Stelle erwartet. Dies sollte jedoch die NuGet-Paketwiederherstellungsfunktion zu Beginn des Erstellungsprozesses starten. Stellen Sie sicher, dass Ihr Ordner \ Solutions \ Packages \ an der gewünschten Stelle erstellt wurde. Wenn dies nicht der Fall ist, überprüfen Sie Ihre Konfiguration.
Nun möchten Sie für jedes Projekt in Ihrer Lösung:
- Klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie Projekt entladen
- Klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie Edit your-xxx.csproj
- Suchen Sie nach Verweisen auf \ packages \ und aktualisieren Sie sie auf den neuen Speicherort.
- Die meisten davon sind <HintPath> -Referenzen, aber nicht alle. Beispielsweise verfügen WebGrease und Microsoft.Bcl.Build über separate Pfadeinstellungen, die aktualisiert werden müssen.
- Speichern Sie die .csproj-Datei, klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie Projekt neu laden
Sobald alle Ihre .csproj-Dateien aktualisiert wurden, starten Sie einen weiteren Rebuild All, und Sie sollten keine Build-Fehler mehr über fehlende Referenzen haben. Zu diesem Zeitpunkt sind Sie fertig und haben NuGet für die Verwendung eines freigegebenen Paketordners konfiguriert.
Ab NuGet 2.7.1 (2.7.40906.75) mit VStudio 2012
Zunächst ist zu beachten, dass nuget.config nicht alle Pfadeinstellungen im Nuget-Paketsystem steuert. Dies war besonders verwirrend herauszufinden. Insbesondere besteht das Problem darin, dass msbuild und Visual Studio (Aufruf von msbuild) den Pfad in nuget.config nicht verwenden, sondern ihn in der Datei nuget.targets überschreiben.
Umweltvorbereitung
Zuerst würde ich den Ordner Ihrer Lösung durchsuchen und alle vorhandenen \ packages \ -Ordner entfernen. Auf diese Weise stellen Sie sicher, dass alle Pakete sichtbar im richtigen Ordner installiert werden, und ermitteln fehlerhafte Pfadreferenzen in Ihren Lösungen. Als Nächstes würde ich sicherstellen, dass Sie die neueste Nuget Visual Studio-Erweiterung installiert haben. Ich würde auch sicherstellen, dass Sie die neueste nuget.exe in jeder Lösung installiert haben. Öffnen Sie eine Eingabeaufforderung, gehen Sie in jeden Ordner $ (SolutionDir) \ .nuget \ und führen Sie den folgenden Befehl aus:
nuget update -self
Festlegen des allgemeinen Paketordnerpfads für NuGet
Öffnen Sie jedes $ (SolutionDir) \ .nuget \ NuGet.Config und fügen Sie im Abschnitt <Konfiguration> Folgendes hinzu:
<config>
<add key="repositorypath" value="$\..\..\..\Packages" />
</config>
Hinweis: Sie können einen absoluten Pfad oder einen relativen Pfad verwenden. Denken Sie daran, wenn Sie einen relativen Pfad mit $ verwenden, der relativ zu einer Ebene unterhalb der Position von NuGet.Config ist (glauben Sie, dass dies ein Fehler ist).
Festlegen des allgemeinen Paketordnerpfads für MSBuild und Visual Studio
Öffnen Sie jedes $ (SolutionDir) \ .nuget \ NuGet.targets und ändern Sie den folgenden Abschnitt (beachten Sie, dass sich für Nicht-Windows ein weiterer Abschnitt darunter befindet):
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
<!-- Windows specific commands -->
<NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
<PackagesConfig>$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
<PackagesDir>$([System.IO.Path]::Combine($(SolutionDir), "packages"))</PackagesDir>
</PropertyGroup>
Aktualisieren Sie PackagesDir auf
<PackagesDir>$([System.IO.Path]::GetFullPath("$(SolutionDir)\..\Packages"))</PackagesDir>
Hinweis: Der GetFullPath löst unseren relativen Pfad in einen absoluten Pfad auf.
Wiederherstellen aller Nuget-Pakete in einem gemeinsamen Ordner
Öffnen Sie eine Eingabeaufforderung, gehen Sie zu jedem $ (SolutionDir) \ .nuget und führen Sie den folgenden Befehl aus:
nuget restore ..\YourSolution.sln
Zu diesem Zeitpunkt sollten Sie einen einzelnen Ordner \ packages \ an Ihrem gemeinsamen Speicherort und keinen in einem Ihrer Lösungsordner haben. Wenn nicht, überprüfen Sie Ihre Pfade.
Projektreferenzen korrigieren
Öffnen Sie jede .csproj-Datei in einem Texteditor, suchen Sie nach Verweisen auf \ packages und aktualisieren Sie sie auf den richtigen Pfad. Die meisten davon sind <HintPath> -Referenzen, aber nicht alle. Beispielsweise verfügen WebGrease und Microsoft.Bcl.Build über separate Pfadeinstellungen, die aktualisiert werden müssen.
Erstellen Sie Ihre Lösung
Öffnen Sie Ihre Lösung in Visual Studio und starten Sie einen Build. Wenn es sich über fehlende Pakete beschwert, die wiederhergestellt werden müssen, gehen Sie nicht davon aus, dass das Paket fehlt und wiederhergestellt werden muss (Fehler können irreführend sein). Es könnte ein schlechter Pfad in einer Ihrer .csproj-Dateien sein. Überprüfen Sie dies zuerst, bevor Sie das Paket wiederherstellen.
Haben Sie einen Build-Fehler bezüglich fehlender Pakete?
Wenn Sie bereits überprüft haben, ob die Pfade in Ihren .csproj-Dateien korrekt sind, haben Sie zwei Möglichkeiten. Wenn dies das Ergebnis der Aktualisierung Ihres Codes aus der Quellcodeverwaltung ist, können Sie versuchen, eine saubere Kopie auszuchecken und diese dann zu erstellen. Dies funktionierte für einen unserer Entwickler und ich denke, es gab ein Artefakt in der .suo-Datei oder etwas Ähnliches. Die andere Option besteht darin, eine Paketwiederherstellung manuell über die Befehlszeile im Ordner .nuget der betreffenden Lösung zu erzwingen:
nuget restore ..\YourSolution.sln
$
vor dem relativen Pfad fehlenden verpasst haben . Auch ist die Antwort auf Ihre Frage zu NuGet.Config Dateien hier . Es wird zuerst in .nuget, dann in allen übergeordneten Verzeichnissen und dann in der 'globalen' Datei in Ihren AppData angezeigt. Anschließend werden sie in der Reihenfolge REVERSE angewendet (was auch immer das bedeutet).