Automatyczne przywracanie pakietu NuGet nie działa z programem MSBuild

111

Próbuję zbudować rozwiązanie z packagesbrakującą zawartością (z wyjątkiem repositories.configwewnątrz) z MSBuild 12.0. Spodziewam się, że automatycznie przywróci wszystkie brakujące pakiety przed rozpoczęciem budowania, ale tak nie jest - MsBuild zgłasza mnóstwo błędów:

„Czy brakuje ci dyrektywy using lub odwołania do zestawu?”

Menedżer NuGet to 2,7 (widzę to w programie Visual Studio 2013 o polu). Próbowałem nawet przekazać EnableNuGetPackageRestore=trueparametr - bez powodzenia. czego mi brakuje?

UserControl
źródło
Czy tworzysz rozwiązanie w programie Visual Studio? Czy wszystko jest zaznaczone w Ustawieniach Menedżera pakietów w sekcji Przywracanie pakietu? Nie potrzebujesz folderu .nuget, jeśli tworzysz w programie Visual Studio i używasz pakietu NuGet 2,7 lub nowszego.
Matt Ward
1
Nie, używam najnowszej wersji MsBuild ( msdn.microsoft.com/en-us/library/hh162058.aspx ) z wiersza poleceń. Zaktualizowano Nugeta z poziomu VS do 2.8 - bez powodzenia.
UserControl
3
Sam MSBuild nie przywróci i dodatek VS. Musisz włączyć przywracanie pakietów, jak powiedział @KMoraz, a następnie, jak powiedział Sumeshk, pojawi się folder .nuget i pakiety mogą zostać przywrócone. Upewnij się, że wpisałeś .nuget w kontroli źródła.
Lex Li,

Odpowiedzi:

36

ZAKTUALIZOWANO o najnowszą oficjalną dokumentację NuGet od wersji 3.3.0

Podejścia do przywracania pakietów

NuGet oferuje trzy podejścia do korzystania z przywracania pakietów .


Automatyczne przywracanie pakietu to zalecane podejście zespołu NuGet do przywracania pakietu w programie Visual Studio i zostało wprowadzone w programie NuGet 2.7. Począwszy od pakietu NuGet 2,7, rozszerzenie NuGet programu Visual Studio integruje się ze zdarzeniami kompilacji programu Visual Studio i przywraca brakujące pakiety po rozpoczęciu kompilacji. Ta funkcja jest domyślnie włączona, ale programiści mogą z niej zrezygnować w razie potrzeby.


Oto jak to działa:

  1. W przypadku kompilacji projektu lub rozwiązania program Visual Studio zgłasza zdarzenie, które rozpoczyna się w rozwiązaniu.
  2. NuGet reaguje na to zdarzenie i sprawdza, czy w rozwiązaniu nie ma plików packages.config.
  3. Dla każdego znalezionego pliku packages.config jego pakiety są wyliczane i sprawdzane, czy istnieją w folderze pakietów rozwiązania.
  4. Wszelkie brakujące pakiety są pobierane ze skonfigurowanych (i włączonych) źródeł pakietów użytkownika, z zachowaniem kolejności źródeł pakietów.
  5. Podczas pobierania pakietów są one rozpakowywane do folderu pakietów rozwiązania.

Jeśli masz zainstalowany Nuget 2.7+; ważne jest, aby wybrać jedną metodę> zarządzania funkcją automatycznego przywracania pakietów w programie Visual Studio.

Dostępne są dwie metody:

  1. (NuGet 2.7+): Visual Studio -> Narzędzia -> Menedżer pakietów -> Ustawienia Menedżera pakietów -> Włącz automatyczne przywracanie pakietów
  2. (Nuget 2.6 i starsze) Kliknięcie rozwiązania prawym przyciskiem myszy i kliknięcie opcji „Włącz przywracanie pakietu dla tego rozwiązania”.


Podczas tworzenia rozwiązania z wiersza polecenia wymagane jest przywracanie pakietu wiersza polecenia; został wprowadzony we wczesnych wersjach NuGet, ale został ulepszony w NuGet 2.7.

nuget.exe restore contoso.sln

Podejście przywracania pakietów zintegrowane z programem MSBuild to oryginalna implementacja przywracania pakietu i chociaż nadal działa w wielu scenariuszach, nie obejmuje pełnego zestawu scenariuszy, do których odnoszą się pozostałe dwa podejścia.

KMoraz
źródło
63
Nie jest to już zalecane przez nuget. Zobacz dokumentację. docs.nuget.org/docs/workflows/…
Owen Johnson
@OwenJohnson, ten dokument nie jest datowany i widzę go, i nie widzę, w jaki sposób jest napisany, że nie jest teraz zalecany? Jestem na VS2013 i ten przycisk wydaje się działać dobrze. Nie mam odniesienia do problemu: „Tak więc kliknąłeś„ Włącz przywracanie pakietu Nuget ”i teraz Twoje rzeczy się nie kompilują. Kroki, aby to naprawić, są bolesne, ale mniej bolesne w przypadku tego skryptu. Github.com/owen2/ AutomaticPackageRestoreMigrationScript Być może istnieje inny dokument, który wyjaśnia to dokładniej.
AnneTheAgile,
5
Automatyczne przywracanie pakietów zastępuje zintegrowane przywracanie MS-build. Dokument zawiera instrukcje dotyczące aktualizacji. Jeśli nie masz problemów z metodą zintegrowaną z msbuildem, nie musisz nic robić. W najprostszych przypadkach działa, ale jeśli masz serwery CI, współdzielone odniesienia do projektów lub inne warunki, możesz nadepnąć na jakieś paskudne miny i mieć nieprawidłowe ścieżki wskazówek lub inne problemy.
Owen Johnson
1
Korzystając z tej odpowiedzi ORAZ wykonując instrukcje „usuń stare rzeczy” „Przeprowadzanie migracji” na docs.nuget.org/consume/package-restore/… , udało mi się odnieść sukces.
granadaCoder
Wygląda na to, że sytuacja ponownie się zmieniła w przypadku pakietu NuGet 4 i standardu .net.
Owen Johnson
239

Jeśli używasz programu Visual Studio 2017 lub nowszego, który jest dostarczany z programemPackageReference MSBuild 15 lub nowszym, a pliki .csproj są w nowym formacie , najprostszą metodą jest użycie nowego elementu Restoredocelowego MSBuild .


Nikt tak naprawdę nie odpowiedział na pierwotne pytanie, które brzmi: „Jak uzyskać automatyczne przywracanie pakietów NuGet podczas kompilowania z wiersza polecenia za pomocą programu MSBuild?” Odpowiedź brzmi: jeśli nie używasz opcji „Włącz przywracanie pakietu NuGet” (która jest obecnie przestarzała zgodnie z tym odniesieniem ), nie możesz (ale zobacz poniżej). Jeśli próbujesz np. Zautomatyzować kompilacje na serwerze CI, jest to do bani.

Istnieje jednak nieco okrężny sposób na uzyskanie pożądanego zachowania:

  1. Pobierz najnowszy plik wykonywalny NuGet z https://dist.nuget.org/win-x86-commandline/latest/nuget.exe i umieść go gdzieś w swojej ścieżce PATH. (Możesz to zrobić jako krok przed kompilacją).
  2. Uruchom, nuget restorektóry automatycznie pobierze wszystkie brakujące pakiety.
  3. Uruchom, msbuildaby zbudować swoje rozwiązanie.

Poza tym: podczas gdy nowy i zalecany sposób automatycznego przywracania pakietów wiąże się z mniejszym bałaganem w kontroli wersji, uniemożliwia również przywracanie pakietów z wiersza poleceń, chyba że przeskoczysz przez dodatkową pętlę pobierania i uruchamiania nuget.exe. Postęp?

Ian Kemp
źródło
Skończyło się podobnym rozwiązaniem (ale umieszczonym nuget.exe w / trunk / ext). Jeden krok do przodu - dwa kroki do tyłu :(
UserControl
40
Powinna to być poprawna odpowiedź, a nie zaznaczona.
Woland
To naprawdę wydaje się być trochę sprzeczne z intuicją, jeśli chodzi o to, ale naprawdę masz więcej funkcji, aby dodać określone pakiety nuget z powrotem za pomocą wiersza poleceń. To rozwiązanie działało u mnie, gdy automatyczne przywracanie nie powiodło się.
TGarrett
2
Używałem Jenkinsa i musiałem to zrobić, był to prosty krok kompilacji przed wywołaniem msbuild - plik wsadowy systemu Windows był typem kroku kompilacji, a: cmd.exe / c "C: \ Program Files \ nuget \ nuget.exe" przywróć < RelativePathToSln> .sln - ścieżkę do SLN zrobiłem jako nawyk / procedurę na wypadek, gdyby nie znalazłem pliku sln.
Steve Radich-BitShop.com
1
To podejście zadziałało podczas konfigurowania przywracania w kompilacji Jenkins. Ważnym dla mnie kluczem było to, że NuGet.Config musiał znajdować się w tym samym katalogu, co mój plik .SLN. Żadna kombinacja innych lokalizacji plików konfiguracyjnych, w tym określenie -ConfigFile w wierszu poleceń, nie zadziała.
Guerry
56

Automatyczne przywracanie pakietu Nuget to funkcja programu Visual Studio (od 2013 r.), A nie MSBuild. Będziesz musiał uruchomić, nuget.exe restorejeśli chcesz przywrócić pakiety z wiersza poleceń.

Możesz również użyć funkcji Włącz przywracanie pakietu Nuget, ale nie jest to już zalecane przez osoby nuget, ponieważ wprowadza uciążliwe zmiany w plikach projektu i może powodować problemy, jeśli utworzysz te projekty w innym rozwiązaniu.

Owen Johnson
źródło
2
Musisz uruchomić „NuGet update -self” przed użyciem polecenia Restore-Command, jeśli wersja NuGet nie jest co najmniej 2,7. Mój pakiet NuGet był w wersji 2.1 i nie rozpoznał polecenia „przywróć” przed aktualizacją.
Teknikaali
2
„powoduje problemy, jeśli zbudujesz te projekty w innym rozwiązaniu” Nie napotkałem jeszcze żadnych problemów i mamy 3 rozwiązania z dziesiątkami projektów (wiele wspólnych rozwiązań). Może miałem szczęście?
Nelson Rothermel
@NelsonRothermel Najbardziej zauważalną problematyczną sytuacją, która może się zdarzyć, są projekty odwołujące się do bibliotek DLL dostarczonych przez NuGet do folderu pakietów rozwiązania obcego, który może być niedostępny podczas tworzenia rozwiązania.
Owen Johnson
2
@OwenJohnson Mamy jeden wspólny folder z pakietami dla wszystkich rozwiązań, więc prawdopodobnie dlatego nie napotkaliśmy problemów.
Nelson Rothermel
17

Zajęło mi trochę czasu, zanim zrozumiałem cały obraz i chciałbym się tutaj podzielić.

Program Visual Studio ma dwa podejścia do korzystania z przywracania pakietów: automatyczne przywracanie pakietów i przywracanie pakietów zintegrowane z programem MSBuild. „Przywracanie pakietów zintegrowanych z programem MSBuild” przywraca pakiety W TRAKCIE procesu tworzenia, które mogą powodować problemy w niektórych scenariuszach. „Automatyczne przywracanie pakietu” to zalecane podejście zespołu NuGet.

Aby „Automatyczne przywracanie pakietów” działało, należy wykonać kilka czynności:

  1. W programie Visual Studio Narzędzia -> Rozszerzenia i aktualizacje Uaktualnij pakiet NuGet, jeśli istnieje nowsza wersja (wersja 2.7 lub nowsza)

  2. Jeśli używasz programu TFS, w folderze .nuget rozwiązania usuń pliki NuGet.exe i NuGet.targes. Następnie edytuj NuGet.Config, aby nie sprawdzać pakietów NuGet:

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

    Jeśli wcześniej zaznaczyłeś folder pakietów rozwiązania do TFS, usuń folder i zaznacz opcję usunięcia usunięcia folderu pakietu.

    Jeśli nie używasz TFS, usuń folder .nuget.

  3. W każdym pliku projektu (.csproj lub .vbproj) w rozwiązaniu usuń wiersz odwołujący się do pliku NuGet.targets. Odniesienie wygląda następująco:

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

    Usuń ten wiersz z każdego pliku projektu w rozwiązaniu.

  4. W menu programu Visual Studio za pośrednictwem

    Narzędzia -> Opcje -> Menedżer pakietów -> Ogólne lub Narzędzia -> Menedżer pakietów NuGet -> Ustawienia Menedżera pakietów

    włącz następujące dwie opcje 1) „Zezwalaj NuGet na pobieranie brakujących pakietów” 2) „Automatycznie sprawdzaj brakujące pakiety podczas kompilacji w programie Visual Studio”

  5. Przetestuj konfigurację przywracania pakietów, wykonując następujące kroki

    • Zapisz swoje rozwiązanie i zamknij program Visual Studio
    • Usuń folder pakietów rozwiązania
    • Uruchom program Visual Studio, otwórz rozwiązanie i odbuduj je.
Ying
źródło
1
Jednym z kroków jest usunięcie <Import Project = "$ (MSBuildToolsPath) \ Microsoft.CSharp.targets" />. Dlaczego chcesz to zrobić?
Ibrahim Hashimi,
3
Myślę, że się mylisz, że jest w samym szablonie. Bez tego twoje pliki źródłowe w ogóle nie zostaną zbudowane.
Ibrahim Hashimi
3
Myślę, że miał na myśli nuget.targets zamiast Microsoft.CSharp.targets.
Owen Johnson
2
docs.nuget.org/docs/workflows/… <- Oto oficjalna dokumentacja tego, co Ying próbował powiedzieć.
Owen Johnson,
1
Tak jest ... to, co wszyscy zignorowali, to fakt, że kompilacje Continuous Integration tworzą własny tymczasowy obszar roboczy PO zdarzeniach przed kompilacją, pobierają źródła, a następnie dławią się odwołaniami NuGet. To jest NAPRAWA automatyzacji kompilacji TFS.
CZahrobsky
5

MSBuild 15 ma opcję / t: Restore , która to robi. jest dostarczany z programem Visual Studio 2017.

Jeśli chcesz tego użyć, musisz również użyć nowego PackageReference , co oznacza zastąpienie packages.configpliku takimi elementami (zrób to w * .csproj):

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

Istnieje automatyczna migracja do tego formatu, jeśli klikniesz prawym przyciskiem myszy `` Referencje '' (może się nie pojawić, jeśli właśnie otworzyłeś Visual Studio, przebudowałeś lub otworzyłeś okno `` Zarządzaj pakietami NuGet dla rozwiązania '' i zacznie się pojawiać).

Chris
źródło
Musisz wziąć pod uwagę, że opcja przywracania programu MSBuild ma subtelne różnice w stosunku do przywracania nuget - zobacz na przykład github.com/NuGet/Home/issues/7651#issuecomment-500842049 .
Matthieu
4

Ian Kemp ma odpowiedź (przy okazji ma kilka punktów), jest to po prostu dodanie mięsa do jednego ze swoich kroków.

Powodem, dla którego tu trafiłem, było to, że maszyny deweloperów budowały się dobrze, ale serwer kompilacji po prostu nie ściągał wymaganych pakietów (pusty folder pakietów) i dlatego kompilacja kończyła się niepowodzeniem. Jednak zalogowanie się do serwera kompilacji i ręczne zbudowanie rozwiązania zadziałało.

Aby wykonać drugi z 3-punktowych kroków Ians (uruchamianie przywracania nuget ), można utworzyć element docelowy MSBuild z uruchomionym poleceniem exec, aby uruchomić polecenie przywracania NuGet, jak poniżej (w tym przypadku plik NuGet.exe znajduje się w folderze .nuget, a nie na ścieżce), który można następnie uruchomić w kroku kompilacji TeamCity (dostępne inne CI ...) bezpośrednio przed budowaniem rozwiązania

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

Dla przypomnienia, wypróbowałem już typ runnera „nuget installer”, ale ten krok zawieszał się w projektach internetowych (działał dla projektów DLL i Windows)

Fetchez la vache
źródło
1
Jeśli ciągle tworzysz z nowego zestawu kodu (CI), to jest właściwy sposób.
Jahmic
1
Podoba mi się to podejście, ponieważ gwarantuje, że każde rozwiązanie / projekt opiera się na wersji nuget, w której zostało utworzone. W odpowiednim czasie może się to okazać kluczowe, jeśli pracujesz w firmie ze starymi projektami, które zostały utworzone przy użyciu starych wersji nuget. Deweloper może obsługiwać takie projekty bez martwienia się o to, czy plik nuget.exe dla całego systemu zepsuje wszystko, ponieważ każdy projekt ma swój własny „lokalny smak” pliku nuget.exe. Na koniec warto zauważyć, że dzięki nuget 3.x + możemy przywracać pakiety, takie jak: nuget.exe przywróć pakiety.config -PackagesDirectory path \ to \ packages
XDS
1
Problem, który mam z tym podejściem polega na tym, że musisz edytować każdy kolejny plik projektu, aby dodać krok przywracania. można dodać działanie „InvokeProcess” w programie TFS2012 lub działanie „NuGetRestore” w szablonie kompilacji TFS2013, aby ten krok był wykonywany na serwerze kompilacji. w przypadku InvokeProcess przekaż atrybut „SourcesDirectory” w 2012 r. W programie TFS 2013 wystarczy wpisać wymagane wartości. jest wiele blogów o tym, jak to zrobić.
Neville
3

Zwróć uwagę, że jeśli używasz TeamCity jako serwera kompilacji, uzyskasz krok „Instalator NuGet”, którego możesz użyć do przywrócenia wszystkich pakietów przed krokiem kompilacji.

Dejan
źródło
2

Istnieje plik packages.config z projektem, zawiera on szczegóły pakietu.

Istnieje również folder .nuget zawierający pliki NuGet.exe i NuGet.targets . jeśli brakuje któregokolwiek z plików, nie przywróci brakującego pakietu i spowoduje, że „brakuje dyrektywy using lub odwołania do zestawu?” błąd

Sumeshk
źródło
2
Nie ma .nugetfolderu i nigdy nie było. Wszystkie packages.configpliki w folderach projektu są na swoich miejscach.
UserControl
Myślę, że NuGet.exe i NuGet.targets automatycznie przywrócą wszystkie brakujące pakiety podczas budowania aplikacji i utraciłeś pliki NuGet.exe i NuGet.targets, to powoduje błędy
Sumeshk
W każdym razie dziękuję - doceniam każdą pomoc!
UserControl
folder .nuget to folder wygenerowany przez program Visual Studio, który pojawia się tylko po włączeniu automatycznego przywracania pakietów. Warto mieć plik NuGet. Exe w repozytorium kodu, ponieważ można odwoływać się do niego w kompilacjach, podobnie jak plik nuget.config (zwłaszcza jeśli trzeba pobrać pakiety z wielu repozytoriów).
MytyMyky
2

Czasami zdarza się to, gdy folder pakietu, który próbujesz przywrócić, znajduje się w folderze „packages” (np. „Packages / EntityFramework.6.0.0 /” ), ale nie ma w nim plików „DLL” (większość funkcji kontroli wersji systemy automatycznie ignorują pliki „.dll”). Dzieje się tak, ponieważ zanim NuGet spróbuje przywrócić każdy pakiet, sprawdza, czy foldery już istnieją, więc jeśli istnieją, NuGet zakłada, że ​​„dll” znajduje się w nim. Jeśli więc jest to problem, po prostu usuń folder, który NuGet przywróci go poprawnie.

fabriciorissetto
źródło
1
W przypadku VS 2015 i TFS to naprawi. Problem będzie nierozwiązany, a często problem polega na tym, że pakiet NuGet nie jest przywracany, ponieważ folder pakietu już istnieje w folderze pakietów, ale pakiet nie został jeszcze w pełni rozwinięty. (Na przykład brak folderu lib, który powinien zawierać plik .dll). Usuń cały folder pakietu w pakietach, a następnie kliknij prawym przyciskiem myszy na poziomie rozwiązania i wybierz opcję przywrócenia pakietów.
Greg
1

Wystąpił problem z pakietami NuGet, które nie były dołączane do nocnej kompilacji skryptowej, która tworzy plik sln przy użyciu devenv.exe.

Postępowałem zgodnie z radą Microsoftu , a kluczowym krokiem było zaktualizowanie konfiguracji NuGet %AppData%/NuGettak, aby zawierała:

<configuration>
    <packageRestore>
        <add key="automatic" value="True" />
    </packageRestore>
</configuration>
PaulG
źródło
Więc sprawdziłem, że kiedy zmieniasz ustawienia w Visual Studio (większość odpowiedzi tutaj) ... powyższe jest faktycznie tym, co się zmienia. drugi „klucz” to <add key = "enabled" value = "False" />.
granadaCoder
0

W programie Visual Studio 2017 - podczas kompilowania przy użyciu środowiska IDE - pobierze wszystkie brakujące pakiety NuGet i zapisze w folderze „packages”.

Ale na maszynie kompilacji kompilacja została wykonana przy użyciu msbuild.exe. W takim przypadku pobrałem plik nuget.exe i zachowałem ścieżkę.

Podczas każdego procesu kompilacji przed uruchomieniem msbuild.exe. Uruchomi się -> nuget.exe przywróci plik NAZWA_F_SLN (jeśli jest tylko jeden plik .SLN, możesz zignorować ten parametr)

David
źródło
0

Możesz także użyć

Update-Package -reinstall

aby przywrócić pakiety NuGet w konsoli zarządzania pakietami w programie Visual Studio.

MovGP0
źródło
To nie jest odpowiedź na to pytanie
TS