Pemulihan paket otomatis NuGet tidak bekerja dengan MSBuild

111

Saya mencoba membangun solusi dengan packageskonten yang hilang (kecuali repositories.configdi dalam) dengan MSBuild 12.0. Saya mengharapkannya untuk secara otomatis mengembalikan semua paket yang hilang sebelum membangun tetapi ini tidak terjadi - MsBuild melaporkan banyak kesalahan:

"Apakah Anda kehilangan petunjuk penggunaan atau referensi perakitan?"

NuGet Manager 2.7 (Saya melihat ini di Visual Studio 2013 tentang kotak). Saya bahkan mencoba untuk memberikan EnableNuGetPackageRestore=trueparameter - tidak berhasil. Apa yang saya lewatkan?

UserControl
sumber
Apakah Anda membangun solusi dalam Visual Studio? Juga apakah semuanya dicentang di Pengaturan Manajer Paket di bagian Pemulihan Paket? Anda tidak memerlukan folder .nuget jika Anda membuat dalam Visual Studio dan menggunakan NuGet 2.7 atau yang lebih baru.
Matt Ward
1
Tidak, saya menggunakan versi MsBuild ( msdn.microsoft.com/en-us/library/hh162058.aspx ) terbaru dari baris perintah. Nuget yang diperbarui dari dalam VS ke 2.8 - tidak berhasil.
UserControl
3
MSBuild sendiri tidak akan memulihkan dan juga addin VS. Anda perlu mengaktifkan pemulihan paket seperti yang dikatakan @KMoraz, dan kemudian seperti yang Sumeshk katakan, folder .nuget muncul dan paket dapat dipulihkan. Pastikan Anda memeriksa .nuget di kontrol sumber.
Lex Li

Jawaban:

36

DIPERBARUI dengan dokumentasi resmi NuGet terbaru pada v3.3.0

Pendekatan Pemulihan Paket

NuGet menawarkan tiga pendekatan untuk menggunakan pemulihan paket .


Pemulihan Paket Otomatis adalah pendekatan yang direkomendasikan tim NuGet untuk Pemulihan Paket dalam Visual Studio, dan itu diperkenalkan di NuGet 2.7. Dimulai dengan NuGet 2.7, ekstensi NuGet Visual Studio terintegrasi ke dalam acara pembuatan Visual Studio dan memulihkan paket yang hilang saat pembuatan dimulai. Fitur ini diaktifkan secara default, tetapi pengembang dapat memilih keluar jika diinginkan.


Begini cara kerjanya:

  1. Pada proyek atau solusi membangun, Visual Studio menimbulkan peristiwa yang membangun dimulai dalam solusi.
  2. NuGet menanggapi acara ini dan memeriksa file package.config yang disertakan dalam solusi.
  3. Untuk setiap file packages.config yang ditemukan, paketnya dihitung dan Diperiksa ada di folder paket solusi.
  4. Semua paket yang hilang diunduh dari sumber paket yang dikonfigurasi (dan diaktifkan) milik pengguna, dengan memperhatikan urutan sumber paket.
  5. Saat paket diunduh, paket tersebut dibuka ritsletingnya ke folder paket solusi.

Jika Anda memasang Nuget 2.7+; penting untuk memilih satu metode untuk> mengelola Pemulihan Paket Otomatis di Visual Studio.

Dua metode tersedia:

  1. (Nuget 2.7+): Visual Studio -> Tools -> Package Manager -> Package Manager Settings -> Enable Automatic Package Restore
  2. (Nuget 2.6 dan yang lebih lama) Klik kanan pada solusi dan klik "Aktifkan Pemulihan Paket untuk solusi ini".


Pemulihan Paket Baris Perintah diperlukan saat membuat solusi dari baris perintah; itu diperkenalkan di versi awal NuGet, tetapi ditingkatkan di NuGet 2.7.

nuget.exe restore contoso.sln

Pendekatan pemulihan paket terintegrasi MSBuild adalah implementasi Pemulihan Paket asli dan meskipun terus bekerja di banyak skenario, pendekatan ini tidak mencakup rangkaian lengkap skenario yang dialamatkan oleh dua pendekatan lainnya.

KMoraz
sumber
63
Ini tidak lagi direkomendasikan oleh nuget. Lihat dokumennya. docs.nuget.org/docs/workflows/…
Owen Johnson
@OwenJohnson, dokumen itu tidak bertanggal yang bisa saya lihat dan saya tidak mengerti bagaimana dikatakannya tidak disarankan sekarang? Saya menggunakan VS2013 dan tombol itu tampaknya berfungsi dengan baik. Saya tidak memiliki masalah yang direferensikan, "Jadi, Anda mengklik" Aktifkan Pemulihan Paket Nuget "dan sekarang barang Anda tidak dapat dibangun. Langkah-langkah untuk memperbaikinya memang menyakitkan, tetapi tidak terlalu menyakitkan dengan skrip ini." Github.com/owen2/ AutomaticPackageRestoreMigrationScript Mungkin ada dokumen lain yang menjelaskan hal ini lebih lanjut.
AnneTheAgile
5
Pemulihan paket otomatis menggantikan pemulihan terintegrasi ms-build. Dokumen tersebut adalah instruksi tentang cara meningkatkan. Jika Anda tidak mengalami masalah dengan metode terintegrasi msbuild, Anda tidak perlu melakukan apa pun. Dalam kasus yang paling sederhana, ini berfungsi, tetapi jika Anda memiliki server CI, referensi proyek bersama, atau beberapa kondisi lain, Anda mungkin menginjak beberapa ranjau darat yang buruk dan memiliki jalur petunjuk yang salah atau masalah lain.
Owen Johnson
1
Menggunakan jawaban ini DAN melakukan instruksi "hapus barang lama" "Melakukan migrasi" di docs.nuget.org/consume/package-restore/… , saya dapat menemukan kesuksesan.
granadaCoder
Sepertinya banyak hal telah berubah lagi dengan standar NuGet 4 dan .net.
Owen Johnson
239

Jika Anda menggunakan Visual Studio 2017 atau yang lebih baru yang dikirimkan dengan MSBuild 15 atau yang lebih baru, dan file .csproj Anda dalam format baruPackageReference , metode yang paling sederhana adalah menggunakan Restoretarget MSBuild baru .


Tidak ada yang benar-benar menjawab pertanyaan awal, yaitu "bagaimana cara agar paket NuGet dipulihkan otomatis saat membangun dari baris perintah dengan MSBuild?" Jawabannya adalah: kecuali Anda menggunakan opsi "Enable NuGet package restore" (yang sekarang sudah tidak digunakan lagi sesuai referensi ini ), Anda tidak bisa (tetapi lihat di bawah). Jika Anda mencoba melakukan, misalnya, pembuatan otomatis pada server CI, ini menyebalkan.

Namun, ada cara yang tidak pasti untuk mendapatkan perilaku yang diinginkan:

  1. Unduh NuGet terbaru yang dapat dieksekusi dari https://dist.nuget.org/win-x86-commandline/latest/nuget.exe dan letakkan di suatu tempat di PATH Anda. (Anda dapat melakukan ini sebagai langkah pra-pembuatan.)
  2. Jalankan nuget restoreyang akan mengunduh otomatis semua paket yang hilang.
  3. Jalankan msbuilduntuk membangun solusi Anda.

Selain itu: meskipun cara baru dan yang disarankan untuk melakukan pemulihan paket otomatis melibatkan lebih sedikit kekacauan dalam kontrol versi Anda, itu juga membuat pemulihan paket baris perintah tidak mungkin kecuali Anda melompat melalui lingkaran ekstra untuk mengunduh dan menjalankan nuget.exe. Kemajuan?

Ian Kemp
sumber
Berakhir dengan solusi serupa (tetapi ditempatkan nuget.exeke / trunk / ext). Satu langkah maju - dua langkah mundur :(
UserControl
40
Jawaban ini harus benar, bukan yang ditandai.
Woland
Ini benar-benar tampaknya sedikit kontra intuitif ketika datang ke sana, tetapi Anda benar-benar mendapatkan lebih banyak fungsi untuk menambahkan kembali paket nuget tertentu dengan menggunakan baris perintah. Solusi ini berfungsi untuk saya saat pemulihan otomatis gagal.
TGarrett
2
Saya menggunakan Jenkins dan harus melakukannya, ini adalah langkah pembuatan yang sederhana sebelum memanggil msbuild - File batch Windows adalah jenis langkah pembuatan dan: cmd.exe / c "C: \ Program Files \ nuget \ nuget.exe" restore < RelativePathToSln> .sln - Saya melakukan jalur ke SLN sebagai kebiasaan / prosedur kalau-kalau tidak menemukan file sln.
Steve Radich-BitShop.com
1
Pendekatan ini berhasil untuk saya saat menyiapkan pemulihan pada build Jenkins. Satu kunci penting bagi saya adalah NuGet.Config harus berada di direktori yang sama dengan file .SLN saya. Tidak ada kombinasi lokasi file konfigurasi lain, termasuk menentukan -ConfigFile pada baris perintah yang akan berfungsi.
Guerry
56

Nuget's Automatic Package Restore adalah fitur dari Visual Studio (mulai tahun 2013), bukan MSBuild. Anda harus menjalankannya nuget.exe restorejika ingin memulihkan paket dari baris perintah.

Anda juga dapat menggunakan fitur Aktifkan Pemulihan Paket Nuget, tetapi ini tidak lagi direkomendasikan oleh orang-orang nuget karena ini membuat perubahan yang mengganggu pada file proyek dan dapat menyebabkan masalah jika Anda membangun proyek tersebut di solusi lain.

Owen Johnson
sumber
2
Anda perlu menjalankan "nuget update -self" sebelum menggunakan perintah restore jika versi NuGet Anda tidak minimal 2.7. NuGet saya adalah versi 2.1 dan tidak mengenali perintah "pulihkan" sebelum memperbarui.
Teknikaali
2
"menyebabkan masalah jika Anda membangun proyek tersebut dalam solusi lain" Saya belum mengalami masalah apa pun dan kami memiliki 3 solusi dengan masing-masing lusinan proyek (banyak yang dibagikan di seluruh solusi). Mungkin saya beruntung?
Nelson Rothermel
@NelsonRothermel situasi bermasalah yang paling menonjol yang dapat terjadi adalah proyek yang mereferensikan dll yang dikirim nuget ke folder paket solusi asing, yang mungkin tidak tersedia ketika Anda membangun solusi.
Owen Johnson
2
@OwenJohnson Kami memiliki satu folder paket umum untuk semua solusi, jadi mungkin itulah sebabnya kami tidak mengalami masalah.
Nelson Rothermel
17

Saya butuh waktu untuk memikirkan keseluruhan gambar dan saya ingin berbagi di sini.

Visual Studio memiliki dua pendekatan untuk menggunakan pemulihan paket: Pemulihan paket otomatis dan pemulihan paket terintegrasi MSBuild. 'Pemulihan Paket Terpadu MSBuild' mengembalikan paket SELAMA proses pembuatan yang mungkin menyebabkan masalah dalam beberapa skenario. 'Pemulihan Paket Otomatis' adalah pendekatan yang direkomendasikan oleh tim NuGet.

Ada beberapa langkah untuk membuat 'Pemulihan Paket Otomatis' berfungsi:

  1. Di Visual Studio, Tools -> Extensions and Updates, Upgrade NuGet jika ada versi yang lebih baru (Versi 2.7 atau yang lebih baru)

  2. Jika Anda menggunakan TFS, di folder .nuget solusi Anda, hapus file NuGet.exe dan NuGet.targes. Kemudian edit NuGet.Config untuk tidak memeriksa paket NuGet:

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

    Jika Anda memeriksa folder paket solusi ke TFS sebelumnya, hapus folder tersebut dan periksa di penghapusan penghapusan folder paket.

    Jika Anda tidak menggunakan TFS, hapus folder .nuget.

  3. Di setiap file proyek (.csproj atau .vbproj) dalam solusi Anda, hapus baris yang mereferensikan file NuGet.t target. Referensi tersebut terlihat seperti ini:

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

    Hapus baris ini di setiap file proyek dalam solusi Anda.

  4. Dalam menu Visual Studio, baik melalui

    Tools -> Options -> Package Manager -> General atau Tools -> NuGet Package Manager -> Package Manager Settings

    harap aktifkan dua opsi berikut 1) 'Izinkan NuGet untuk mengunduh paket yang hilang' 2) 'Secara otomatis memeriksa paket yang hilang selama pembuatan di Visual Studio'

  5. Uji konfigurasi pemulihan paket Anda dengan langkah-langkah berikut

    • Simpan solusi Anda dan tutup Visual Studio
    • Hapus folder paket solusi Anda
    • Mulai Visual Studio, buka solusi Anda dan bangun kembali.
Ying
sumber
1
Salah satu langkah Anda adalah menghapus <Import Project = "$ (MSBuildToolsPath) \ Microsoft.CSharp.t Target" />. Kenapa kamu ingin melakukan itu?
Sayed Ibrahim Hashimi
3
Saya pikir Anda salah yang ada di template itu sendiri. Tanpa itu, file sumber Anda tidak akan dibuat sama sekali.
Sayed Ibrahim Hashimi
3
Saya pikir yang dia maksud adalah nuget.t target daripada Microsoft.CSharp.t target.
Owen Johnson
2
docs.nuget.org/docs/workflows/… <- Ini adalah dokumen resmi dari apa yang ingin dikatakan Ying.
Owen Johnson
1
Ying benar ... apa yang diabaikan semua orang adalah fakta bahwa Continuous Integration membangun ruang kerja sementara mereka sendiri SETELAH acara pra-pembuatan, dapatkan sumber, dan kemudian tersedak referensi NuGet. Ini adalah PERBAIKAN untuk otomatisasi build TFS.
CZahrobsky
5

MSBuild 15 memiliki opsi / t: restore yang melakukan ini. itu datang dengan Visual Studio 2017.

Jika ingin menggunakan ini, Anda juga harus menggunakan yang baru PackageReference , yang berarti mengganti packages.configfile dengan elemen seperti ini (lakukan ini di * .csproj):

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

Ada migrasi otomatis ke format ini jika Anda mengklik kanan pada 'Referensi' (ini mungkin tidak muncul jika Anda baru saja membuka studio visual, membangun kembali atau membuka jendela 'Kelola paket NuGet untuk solusi' dan itu akan mulai muncul).

Chris
sumber
Anda harus mempertimbangkan bahwa opsi pemulihan msbuild memiliki perbedaan halus dari nuget restore - lihat github.com/NuGet/Home/issues/7651#issuecomment-500842049 misalnya.
Matthieu
4

Ian Kemp punya jawabannya (ada beberapa poin btw ..), ini hanya menambahkan sedikit daging ke salah satu langkahnya.

Alasan saya berakhir di sini adalah karena mesin dev sedang membangun dengan baik, tetapi server build tidak menarik paket yang diperlukan (folder paket kosong) dan oleh karena itu build gagal. Namun, masuk ke server build dan membuat solusi secara manual berhasil.

Untuk memenuhi langkah kedua dari Ians 3 point (menjalankan nuget restore ), Anda dapat membuat target MSBuild yang menjalankan perintah exec untuk menjalankan perintah nuget restore, seperti di bawah ini (dalam hal ini nuget.exe ada di folder .nuget, daripada di jalur), yang kemudian dapat dijalankan dalam langkah pembuatan TeamCity (CI lain tersedia ...) segera sebelum membuat solusi

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

Sebagai catatan, saya sudah mencoba jenis runner "nuget installer" tetapi langkah ini tergantung pada proyek web (bekerja untuk proyek DLL dan Windows)

Fetchez la vache
sumber
1
Jika Anda terus-menerus membangun dari satu set kode (CI) baru, inilah cara yang tepat.
Jahmic
1
Saya agak suka pendekatan ini karena menjamin bahwa setiap solusi / proyek bergantung pada versi nuget yang dibuat dengannya. Pada waktunya, hal ini terbukti penting jika Anda bekerja di perusahaan dengan proyek lama yang dibuat menggunakan nuget versi lama. Seorang dev dapat memelihara proyek tersebut tanpa harus khawatir apakah nuget.exe di seluruh sistem akan merusak banyak hal karena setiap proyek memiliki "rasa lokal" sendiri dari nuget.exe. Sebagai tip terakhir, perlu dicatat bahwa dengan nuget 3.x + kita dapat memulihkan paket seperti: nuget.exe mengembalikan paket.config -PackagesDirectory path \ to \ packages
XDS
1
Masalah yang saya hadapi dengan pendekatan ini adalah Anda harus mengedit file proyek berikutnya untuk menambahkan langkah pemulihan. Anda dapat menambahkan aktivitas "InvokeProcess" di TFS2012 atau aktivitas "NuGetRestore" di template build TFS2013 agar langkah ini dijalankan di server build. untuk InvokeProcess, berikan atribut "SourcesDirectory" pada tahun 2012. Di TFS 2013, cukup isi nilai yang diperlukan. ada banyak blog tentang cara melakukan ini.
Neville
3

Perhatikan bahwa jika Anda menggunakan TeamCity sebagai server build, Anda mendapatkan langkah "Pemasang NuGet" yang dapat Anda gunakan untuk memulihkan semua paket sebelum langkah pembuatan.

Dejan
sumber
2

Ada paket.config file dengan proyek, itu berisi detail paket.

Juga ada folder .nuget yang berisi NuGet.exe dan NuGet.t target . jika salah satu dari file hilang itu tidak akan mengembalikan paket yang hilang dan menyebabkan "apakah Anda kehilangan petunjuk penggunaan atau referensi perakitan?" kesalahan

Sumeshk
sumber
2
Tidak ada .nugetfolder dan tidak pernah ada. Semua packages.configfile dalam folder proyek ada di tempatnya.
UserControl
Saya pikir NuGet.exe dan NuGet.t target akan secara otomatis mengembalikan semua paket yang hilang saat membangun aplikasi dan Anda kehilangan file NuGet.exe dan NuGet.target, itu menyebabkan kesalahan
Sumeshk
Terima kasih -Aku menghargai bantuan apapun!
UserControl
folder .nuget adalah folder yang dibuat Visual Studio, yang muncul hanya ketika Anda mengaktifkan pemulihan paket otomatis. Sangat berguna untuk memiliki nuget.exe di repo kode Anda, karena Anda dapat mereferensikannya di build Anda, seperti nuget.config (terutama jika Anda perlu mendapatkan paket dari banyak repo).
MytyMyky
2

Kadang-kadang hal ini terjadi ketika Anda memiliki folder paket yang Anda coba pulihkan di dalam folder "paket" (yaitu "Paket / EntityFramework.6.0.0 /" ) tetapi "DLL" tidak ada di dalamnya (sebagian besar kontrol versi sistem secara otomatis mengabaikan file ".dll"). Ini terjadi karena sebelum NuGet mencoba mengembalikan setiap paket, ia memeriksa apakah foldernya sudah ada, jadi jika ada, NuGet mengasumsikan bahwa "dll" ada di dalamnya. Jadi jika ini adalah masalah Anda, hapus saja folder yang NuGet akan pulihkan dengan benar.

fabriciorissetto.dll
sumber
1
Untuk VS 2015 dan TFS, ini akan memperbaiki Anda. Masalahnya adalah referensi tidak terselesaikan, dan seringkali masalahnya adalah paket nuget tidak dipulihkan karena folder untuk paket sudah ada di folder paket, tetapi paket belum sepenuhnya diperluas dengan benar. (Seperti kehilangan folder lib yang seharusnya berisi .dll.) Hapus seluruh folder untuk paket di dalam paket, lalu klik kanan di tingkat solusi dan pilih untuk memulihkan paket.
Greg
1

Saya memiliki masalah dengan paket nuget yang tidak disertakan dalam skrip nightly build yang membangun file sln menggunakan devenv.exe.

Saya mengikuti saran dari Microsoft , dan langkah kuncinya adalah memperbarui konfigurasi NuGet %AppData%/NuGetsehingga berisi:

<configuration>
    <packageRestore>
        <add key="automatic" value="True" />
    </packageRestore>
</configuration>
PaulG
sumber
Jadi saya memverifikasi bahwa ketika Anda mengubah pengaturan di Visual Studio (sebagian besar jawabannya di sini) .... di atas sebenarnya apa yang berubah. "kunci" lainnya adalah <add key = "enabled" value = "False" />.
granadaCoder
0

Dalam Visual Studio 2017 - Ketika Anda mengkompilasi menggunakan IDE - Ini akan mengunduh semua paket nuget yang hilang dan menyimpannya di folder "paket".

Tetapi pada kompilasi mesin build dilakukan menggunakan msbuild.exe. Dalam hal ini, saya mengunduh nuget.exe dan tetap di jalur.

Selama setiap proses pembuatan sebelum menjalankan msbuild.exe. Ini akan mengeksekusi -> nuget.exe mengembalikan NAME_OF_SLN_File (jika hanya ada satu file .SLN maka Anda dapat mengabaikan parameter itu)

David
sumber
0

Anda juga bisa menggunakan

Update-Package -reinstall

untuk memulihkan paket NuGet di konsol manajemen paket di Visual Studio.

MovGP0
sumber
Ini bukan jawaban untuk pertanyaan ini
TS