Die automatische Wiederherstellung von NuGet-Paketen funktioniert nicht mit MSBuild

111

Ich versuche mit MSBuild 12.0 eine Lösung mit packagesfehlendem Inhalt (außer im repositories.configInneren) zu erstellen. Ich erwarte, dass alle fehlenden Pakete vor dem Erstellen automatisch wiederhergestellt werden, aber dies ist nicht der Fall - MsBuild meldet Unmengen von Fehlern:

"Fehlt Ihnen eine using-Direktive oder eine Assembly-Referenz?"

NuGet Manager ist 2.7 (ich sehe dies in Visual Studio 2013 über Box). Ich habe sogar versucht, EnableNuGetPackageRestore=trueParameter zu übergeben - kein Glück. Was vermisse ich?

Nutzerkontrolle
quelle
Erstellen Sie die Lösung in Visual Studio? Ist in den Package Manager-Einstellungen im Abschnitt Package Restore auch alles angekreuzt? Sie benötigen den Ordner .nuget nicht, wenn Sie in Visual Studio erstellen und NuGet 2.7 oder höher verwenden.
Matt Ward
1
Nein, ich verwende die neueste Version von MsBuild ( msdn.microsoft.com/en-us/library/hh162058.aspx ) über die Befehlszeile. Nuget von VS auf 2.8 aktualisiert - kein Glück.
UserControl
3
MSBuild allein wird nicht wiederhergestellt und das VS-Add-In auch nicht. Sie müssen die Paketwiederherstellung aktivieren, wie @KMoraz sagte, und dann, wie Sumeshk sagte, wird der Ordner .nuget angezeigt und Pakete können wiederhergestellt werden. Stellen Sie sicher, dass Sie .nuget in die Quellcodeverwaltung einchecken.
Lex Li

Antworten:

36

AKTUALISIERT mit der neuesten offiziellen NuGet-Dokumentation ab Version 3.3.0

Ansätze zur Paketwiederherstellung

NuGet bietet drei Ansätze zur Verwendung der Paketwiederherstellung .


Die automatische Paketwiederherstellung ist der vom NuGet-Team empfohlene Ansatz zur Paketwiederherstellung in Visual Studio und wurde in NuGet 2.7 eingeführt. Ab NuGet 2.7 wird die NuGet Visual Studio-Erweiterung in die Build-Ereignisse von Visual Studio integriert und stellt fehlende Pakete wieder her, wenn ein Build beginnt. Diese Funktion ist standardmäßig aktiviert, Entwickler können sie jedoch bei Bedarf deaktivieren.


So funktioniert das:

  1. Beim Erstellen eines Projekts oder einer Lösung löst Visual Studio das Ereignis aus, dass ein Build innerhalb der Lösung beginnt.
  2. NuGet reagiert auf dieses Ereignis und sucht nach Paketen.config-Dateien, die in der Lösung enthalten sind.
  3. Für jede gefundene Datei packages.config werden die Pakete aufgelistet und im Paketordner der Lösung auf Vorhanden geprüft überprüft.
  4. Fehlende Pakete werden aus den konfigurierten (und aktivierten) Paketquellen des Benutzers heruntergeladen, wobei die Reihenfolge der Paketquellen berücksichtigt wird.
  5. Wenn Pakete heruntergeladen werden, werden sie in den Paketordner der Lösung entpackt.

Wenn Sie Nuget 2.7+ installiert haben; Es ist wichtig, eine Methode zum> Verwalten der automatischen Paketwiederherstellung in Visual Studio auszuwählen.

Es stehen zwei Methoden zur Verfügung:

  1. (Nuget 2.7+): Visual Studio -> Extras -> Paketmanager -> Paketmanagereinstellungen -> Automatische Paketwiederherstellung aktivieren
  2. (Nuget 2.6 und niedriger) Klicken Sie mit der rechten Maustaste auf eine Lösung und klicken Sie auf "Paketwiederherstellung für diese Lösung aktivieren".


Die Wiederherstellung eines Befehlszeilenpakets ist erforderlich, wenn eine Lösung über die Befehlszeile erstellt wird. Es wurde in früheren Versionen von NuGet eingeführt, aber in NuGet 2.7 verbessert.

nuget.exe restore contoso.sln

Der in MSBuild integrierte Paketwiederherstellungsansatz ist die ursprüngliche Implementierung der Paketwiederherstellung. Obwohl er in vielen Szenarien weiterhin funktioniert, deckt er nicht alle Szenarien ab, die von den beiden anderen Ansätzen behandelt werden.

KMoraz
quelle
63
Dies wird von nuget nicht mehr empfohlen. Siehe die Dokumente. docs.nuget.org/docs/workflows/…
Owen Johnson
@OwenJohnson, dieses Dokument ist nicht datiert, das ich sehen kann, und ich sehe nicht, wie es sagt, dass es jetzt nicht empfohlen wird? Ich bin auf VS2013 und diese Schaltfläche scheint gut zu funktionieren. Ich hatte nicht das Problem, auf das verwiesen wurde: "Sie haben also auf" Nuget-Paketwiederherstellung aktivieren "geklickt, und jetzt werden Ihre Daten nicht mehr erstellt. Die Schritte zur Behebung sind schmerzhaft, aber mit diesem Skript weniger schmerzhaft." Github.com/owen2/ AutomaticPackageRestoreMigrationScript Vielleicht gibt es ein anderes Dokument, das dies weiter erklärt.
AnneTheAgile
5
Die automatische Paketwiederherstellung ersetzt die integrierte Wiederherstellung von ms-build. Das Dokument enthält Anweisungen zum Upgrade. Wenn Sie keine Probleme mit der in msbuild integrierten Methode haben, müssen Sie nichts tun. In den einfachsten Fällen funktioniert es, aber wenn Sie CI-Server, freigegebene Projektreferenzen oder andere Bedingungen haben, können Sie auf böse Landminen treten und falsche Hinweispfade oder andere Probleme haben.
Owen Johnson
1
Mit dieser Antwort UND den Anweisungen "Durchführen alter Inhalte " "Durchführen der Migration" unter docs.nuget.org/consume/package-restore/… konnte ich Erfolg erzielen.
GranadaCoder
Es sieht so aus, als hätten sich die Dinge mit NuGet 4 und .net Standard wieder geändert.
Owen Johnson
239

Wenn Sie Visual Studio 2017 oder höher verwenden, das mit MSBuild 15 oder höher geliefert wirdPackageReference , und Ihre .csproj-Dateien im neuen Format vorliegen , ist die einfachste Methode die Verwendung des neuen MSBuild- RestoreZiels .


Niemand hat tatsächlich die ursprüngliche Frage beantwortet: "Wie kann ich NuGet-Pakete beim Erstellen über die Befehlszeile mit MSBuild automatisch wiederherstellen?" Die Antwort lautet: Wenn Sie nicht die Option "NuGet-Paketwiederherstellung aktivieren" verwenden (die jetzt gemäß dieser Referenz veraltet ist ), können Sie dies nicht (siehe unten). Wenn Sie versuchen, z. B. automatisierte Builds auf einem CI-Server durchzuführen, ist dies zum Kotzen.

Es gibt jedoch einen kleinen Umweg, um das gewünschte Verhalten zu erreichen:

  1. Laden Sie die neueste ausführbare NuGet-Datei von https://dist.nuget.org/win-x86-commandline/latest/nuget.exe herunter und platzieren Sie sie irgendwo in Ihrem PATH. (Sie können dies als vorgefertigten Schritt ausführen.)
  2. Führen Sie aus, nuget restorewodurch alle fehlenden Pakete automatisch heruntergeladen werden.
  3. Führen Sie aus msbuild, um Ihre Lösung zu erstellen.

Nebenbei: Während die neue und empfohlene Methode zur automatischen Paketwiederherstellung weniger Unordnung in Ihrer Versionskontrolle mit sich bringt, macht sie auch die Wiederherstellung von Befehlszeilenpaketen unmöglich, es sei denn, Sie springen durch den zusätzlichen Rahmen des Herunterladens und Ausführens nuget.exe. Fortschritt?

Ian Kemp
quelle
Endete mit einer ähnlichen Lösung (aber platziert nuget.exein / trunk / ext). Ein Schritt vorwärts - zwei Schritte zurück :(
UserControl
40
Dies sollte eine korrekte Antwort sein, nicht die markierte.
Woland
Dies scheint wirklich ein wenig kontraintuitiv zu sein, wenn es darauf ankommt, aber Sie erhalten wirklich mehr Funktionen, um bestimmte Nuget-Pakete über die Befehlszeile wieder hinzuzufügen. Diese Lösung hat bei mir funktioniert, während die automatische Wiederherstellung fehlgeschlagen ist.
TGarrett
2
Ich habe Jenkins verwendet und musste dies tun. Es war ein einfacher Erstellungsschritt, bevor ich msbuild aufrief. Die Windows-Batchdatei war der Erstellungsschritttyp und: cmd.exe / c "C: \ Programme \ nuget \ nuget.exe" restore < RelativePathToSln> .sln - Ich habe den Pfad zu SLN als Gewohnheit / Prozedur erstellt, nur für den Fall, dass die sln-Datei nicht gefunden wurde.
Steve Radich-BitShop.com
1
Dieser Ansatz hat bei mir funktioniert, als ich eine Wiederherstellung für einen Jenkins-Build eingerichtet habe. Ein wichtiger Schlüssel für mich war , dass die NuGet.Config hatte im selben Verzeichnis wie meine SLN - Datei sein. Keine Kombination anderer Speicherorte für Konfigurationsdateien, einschließlich der Angabe von -ConfigFile in der Befehlszeile, würde funktionieren.
Guerry
56

Die automatische Paketwiederherstellung von Nuget ist eine Funktion von Visual Studio (ab 2013), nicht von MSBuild. Sie müssen ausgeführt werden, nuget.exe restorewenn Sie Pakete über die Befehlszeile wiederherstellen möchten.

Sie können auch die Funktion "Nuget-Paketwiederherstellung aktivieren" verwenden. Dies wird jedoch von den Nuget-Mitarbeitern nicht mehr empfohlen, da dadurch aufdringliche Änderungen an den Projektdateien vorgenommen werden und Probleme auftreten können, wenn Sie diese Projekte in einer anderen Lösung erstellen.

Owen Johnson
quelle
2
Sie müssen "nuget update -self" ausführen, bevor Sie den Wiederherstellungsbefehl verwenden können, wenn Ihre NuGet-Version nicht mindestens 2.7 ist. Mein NuGet war Version 2.1 und hat den Befehl "Wiederherstellen" vor dem Update nicht erkannt.
Teknikaali
2
"verursacht Probleme, wenn Sie diese Projekte in einer anderen Lösung erstellen" Ich habe noch keine Probleme festgestellt und wir haben 3 Lösungen mit jeweils Dutzenden von Projekten (von denen viele lösungsübergreifend sind). Vielleicht habe ich Glück gehabt?
Nelson Rothermel
@NelsonRothermel Die bemerkenswerteste problematische Situation, die auftreten kann, sind Projekte, die von Nuget gelieferte DLLs auf den Paketordner einer fremden Lösung verweisen, die beim Erstellen einer Lösung möglicherweise nicht verfügbar sind.
Owen Johnson
2
@OwenJohnson Wir haben einen gemeinsamen Paketordner für alle Lösungen, daher sind wir wahrscheinlich nicht auf Probleme gestoßen.
Nelson Rothermel
17

Ich habe einige Zeit gebraucht, um das ganze Bild herauszufinden, und ich möchte es hier teilen.

Visual Studio bietet zwei Ansätze zur Verwendung der Paketwiederherstellung: Automatische Paketwiederherstellung und MSBuild-integrierte Paketwiederherstellung. Die 'MSBuild-integrierte Paketwiederherstellung' stellt Pakete WÄHREND des Erstellungsprozesses wieder her, die in einigen Szenarien Probleme verursachen können. Die "automatische Paketwiederherstellung" wird vom NuGet-Team empfohlen .

Es gibt mehrere Schritte, damit die automatische Paketwiederherstellung funktioniert:

  1. Aktualisieren Sie in Visual Studio unter Extras -> Erweiterungen und Updates NuGet, wenn es eine neuere Version gibt (Version 2.7 oder höher).

  2. Wenn Sie TFS verwenden, entfernen Sie im Ordner .nuget Ihrer Lösung die Dateien NuGet.exe und NuGet.targes. Bearbeiten Sie dann NuGet.Config, um NuGet-Pakete nicht einzuchecken:

    <configuration>  
      <solution>  
        <add key="disableSourceControlIntegration" value="true" />  
      </solution>  
    </configuration> 

    Wenn Sie zuvor den Paketordner der Lösung in TFS eingecheckt haben, löschen Sie den Ordner und aktivieren Sie das Löschen des Paketordners.

    Wenn Sie TFS nicht verwenden, löschen Sie den Ordner .nuget.

  3. Entfernen Sie in jeder Projektdatei (.csproj oder .vbproj) in Ihrer Lösung die Zeile, die auf die Datei NuGet.targets verweist. Die Referenz sieht folgendermaßen aus:

    <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />

    Entfernen Sie diese Zeile in jeder Projektdatei in Ihrer Lösung.

  4. Im Visual Studio-Menü entweder durch

    Extras -> Optionen -> Paketmanager -> Allgemein oder Extras -> NuGet-Paketmanager -> Paketmanagereinstellungen

    Bitte aktivieren Sie die folgenden beiden Optionen: 1) 'NuGet darf fehlende Pakete herunterladen' 2) 'Beim Erstellen in Visual Studio automatisch nach fehlenden Paketen suchen'

  5. Testen Sie die Konfiguration Ihrer Paketwiederherstellung anhand der folgenden Schritte

    • Speichern Sie Ihre Lösung und schließen Sie Visual Studio
    • Löschen Sie den Paketordner Ihrer Lösung
    • Starten Sie Visual Studio, öffnen Sie Ihre Lösung und erstellen Sie sie neu.
Ying
quelle
1
Einer Ihrer Schritte besteht darin, <Import Project = "$ (MSBuildToolsPath) \ Microsoft.CSharp.targets" /> zu entfernen. Warum würdest du das tun?
Sagte Ibrahim Hashimi
3
Ich denke, Sie irren sich, dass in der Vorlage selbst ist. Ohne sie werden Ihre Quelldateien überhaupt nicht erstellt.
Sagte Ibrahim Hashimi
3
Ich denke, er meinte nuget.targets anstelle von Microsoft.CSharp.targets.
Owen Johnson
2
docs.nuget.org/docs/workflows/… <- Hier sind die offiziellen Dokumente dessen, was Ying zu sagen versuchte.
Owen Johnson
1
Ying ist richtig ... was jeder ignoriert hat, ist die Tatsache, dass Continuous Integration-Builds NACH den Pre-Build-Ereignissen ihren eigenen temporären Arbeitsbereich erstellen, Quellen abrufen und dann an NuGet-Referenzen ersticken. Dies ist DAS FIX für die TFS-Build-Automatisierung.
CZahrobsky
5

MSBuild 15 verfügt über eine / t: Wiederherstellungsoption , die dies ausführt . es kommt mit Visual Studio 2017.

Wenn Sie dies verwenden möchten, müssen Sie auch die neue PackageReference verwenden. Dies bedeutet, dass Sie die packages.configDatei durch Elemente wie dieses ersetzen müssen (tun Sie dies in * .csproj):

<ItemGroup>
  <!-- ... -->
  <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
  <!-- ... -->
</ItemGroup>

Wenn Sie mit der rechten Maustaste auf "Referenzen" klicken, erfolgt eine automatische Migration in dieses Format (diese wird möglicherweise nicht angezeigt, wenn Sie gerade Visual Studio geöffnet, das Fenster "NuGet-Pakete für Lösung verwalten" neu erstellt oder geöffnet haben und es wird angezeigt).

Chris
quelle
Sie müssen berücksichtigen, dass die Wiederherstellungsoption von msbuild geringfügige Unterschiede zur Nuget-Wiederherstellung aufweist - siehe z. B. github.com/NuGet/Home/issues/7651#issuecomment-500842049 .
Matthieu
4

Ian Kemp hat die Antwort (habe übrigens einige Punkte), dies ist, einfach etwas Fleisch zu einem seiner Schritte hinzuzufügen.

Der Grund, warum ich hier gelandet bin, war, dass die Maschinen der Entwickler gut gebaut wurden, aber der Build-Server einfach nicht die erforderlichen Pakete herunterzog (leerer Paketordner) und daher der Build fehlschlug. Die Anmeldung am Build-Server und das manuelle Erstellen der Lösung funktionierten jedoch.

Um den zweiten von Ians 3-Punkt-Schritten (Ausführen der Nuget-Wiederherstellung ) auszuführen, können Sie ein MSBuild-Ziel erstellen, auf dem der Befehl exec ausgeführt wird, um den Befehl Nuget-Wiederherstellung wie folgt auszuführen (in diesem Fall befindet sich nuget.exe im Ordner .nuget und nicht auf dem Pfad), der dann in einem TeamCity-Erstellungsschritt (anderes verfügbares CI ...) unmittelbar vor dem Erstellen der Lösung ausgeführt werden kann

<Target Name="BeforeBuild">
  <Exec Command="..\.nuget\nuget restore ..\MySolution.sln"/>
</Target>

Für die Aufzeichnung hatte ich bereits den Runner-Typ "Nuget Installer" ausprobiert, aber dieser Schritt hing an Webprojekten (funktionierte für DLL- und Windows-Projekte).

Fetchez la vache
quelle
1
Wenn Sie ständig aus einem neuen Satz von Code (CI) erstellen, ist dies der richtige Weg.
Jahmic
1
Ich mag diesen Ansatz irgendwie, weil er garantiert, dass jede Lösung / jedes Projekt auf der Version von Nuget basiert, mit der es erstellt wurde. Zu gegebener Zeit kann dies von entscheidender Bedeutung sein, wenn Sie in einem Unternehmen mit alten Projekten arbeiten, die mit alten Nuget-Versionen erstellt wurden. Ein Entwickler kann solche Projekte verwalten, ohne sich Gedanken darüber machen zu müssen, ob die systemweite Datei nuget.exe Probleme verursacht, da jedes Projekt seine eigene "lokale Variante" von nuget.exe hat. Als letzten Tipp ist es erwähnenswert, dass wir mit nuget 3.x + Pakete wie folgt wiederherstellen können: nuget.exe restore packages.config -PackagesDirectory path \ to \ packages
XDS
1
Das Problem bei diesem Ansatz ist, dass Sie alle nachfolgenden Projektdateien bearbeiten müssen, um den Wiederherstellungsschritt hinzuzufügen. Sie können eine "InvokeProcess" -Aktivität in TFS2012 oder eine "NuGetRestore" -Aktivität in der TFS2013-Buildvorlage hinzufügen, damit dieser Schritt auf dem Buildserver ausgeführt wird. Übergeben Sie für InvokeProcess 2012 das Attribut "SourcesDirectory". Geben Sie in TFS 2013 einfach die erforderlichen Werte ein. Es gibt viele Blogs darüber, wie das geht.
Neville
3

Beachten Sie, dass Sie, wenn Sie TeamCity als Build-Server verwenden, einen "NuGet Installer" -Schritt erhalten , mit dem Sie alle Pakete vor dem Build-Schritt wiederherstellen können.

Dejan
quelle
2

Es gibt eine packages.configDas Projekt enthält Datei , die die Paketdetails enthält.

Außerdem gibt es einen .nuget-Ordner, der die NuGet.exe- und NuGet.targets enthält . Wenn eine der Dateien fehlt, wird das fehlende Paket nicht wiederhergestellt und die Ursache "Fehlt Ihnen eine using-Direktive oder eine Assembly-Referenz?" Error

Sumeshk
quelle
2
Es gibt keinen .nugetOrdner und war es nie. Alle packages.configDateien in den Projektordnern sind vorhanden.
UserControl
Ich denke, NuGet.exe und NuGet.targets stellen automatisch alle fehlenden Pakete wieder her, während Sie die App erstellen, und Sie haben Ihre NuGet.exe- und NuGet.targets-Dateien verloren, das führt zu Fehlern
Sumeshk
Trotzdem danke - ich freue mich über jede Hilfe!
UserControl
Der .nuget-Ordner ist ein von Visual Studio generierter Ordner, der nur angezeigt wird, wenn Sie die automatische Paketwiederherstellung aktivieren. Es ist nützlich, die Datei nuget.exe in Ihrem Code-Repo zu haben, da Sie in Ihren Builds darauf verweisen können, ebenso wie die Datei nuget.config (insbesondere, wenn Sie Pakete von mehreren Repos abrufen müssen).
MytyMyky
2

Manchmal tritt dies auf, wenn sich der Ordner des Pakets, das Sie wiederherstellen möchten , im Ordner "packages" befindet (dh "Packages / EntityFramework.6.0.0 /" ) , die "DLLs" jedoch nicht darin enthalten sind (der größte Teil der Versionskontrolle) Systeme ignorieren automatisch ".dll" -Dateien). Dies liegt daran, dass NuGet vor dem Versuch, jedes Paket wiederherzustellen, prüft, ob die Ordner bereits vorhanden sind. Wenn es also vorhanden ist, geht NuGet davon aus, dass sich die "DLL" darin befindet. Wenn dies das Problem für Sie ist, löschen Sie einfach den Ordner, den NuGet korrekt wiederherstellt.

Fabriciorissetto
quelle
1
Für VS 2015 und TFS werden Sie dadurch behoben. Das Problem ist eine Referenz, die nicht behoben wurde, und häufig besteht das Problem darin, dass das Nuget-Paket nicht wiederhergestellt wird, da der Ordner für das Paket bereits im Paketordner vorhanden ist, das Paket jedoch noch nicht vollständig erweitert wurde. (Zum Beispiel fehlt ein lib-Ordner, der eine DLL enthalten sollte.) Löschen Sie den gesamten Ordner für das Paket innerhalb der Pakete, klicken Sie mit der rechten Maustaste auf die Lösungsebene und wählen Sie die Wiederherstellung der Pakete aus.
Greg
1

Ich hatte ein Problem mit Nuget-Paketen, die nicht in einem nächtlichen Build mit Skript enthalten waren, der die sln-Datei mit devenv.exe erstellt.

Ich folgte den Ratschlägen von Microsoft und der wichtigste Schritt bestand darin, die NuGet-Konfiguration %AppData%/NuGetso zu aktualisieren , dass sie Folgendes enthielt:

<configuration>
    <packageRestore>
        <add key="automatic" value="True" />
    </packageRestore>
</configuration>
PaulG
quelle
Ich habe also überprüft, ob beim Ändern der Einstellungen in Visual Studio (die meisten Antworten hier) ... das oben Gesagte tatsächlich geändert wird. Der andere "Schlüssel" ist <add key = "enabled" value = "False" />.
GranadaCoder
0

In Visual Studio 2017 - Wenn Sie mit IDE kompilieren - werden alle fehlenden Nuget-Pakete heruntergeladen und im Ordner "packages" gespeichert.

Auf der Build-Maschine wurde die Kompilierung jedoch mit msbuild.exe durchgeführt. In diesem Fall habe ich nuget.exe heruntergeladen und den Pfad beibehalten.

Während jedes Erstellungsprozesses vor der Ausführung von msbuild.exe. Es wird ausgeführt -> nuget.exe wiederherstellen NAME_OF_SLN_File (wenn es nur eine .SLN-Datei gibt, können Sie diesen Parameter ignorieren)

David
quelle
0

Sie können auch verwenden

Update-Package -reinstall

So stellen Sie die NuGet-Pakete in der Paketverwaltungskonsole in Visual Studio wieder her.

MovGP0
quelle
Dies ist keine Antwort auf diese Frage
TS