Khôi phục gói tự động NuGet không hoạt động với MSBuild


111

Tôi đang cố gắng xây dựng một giải pháp packagesthiếu nội dung (ngoại trừrepositories.config bên trong) với MSBuild 12.0. Tôi hy vọng nó sẽ tự động khôi phục tất cả các gói bị thiếu trước khi xây dựng nhưng đây không phải là trường hợp - MsBuild báo cáo rất nhiều lỗi:

"bạn đang thiếu một chỉ thị đang sử dụng hoặc một tham chiếu hợp ngữ?"

NuGet Manager là 2.7 (Tôi thấy điều này trong hộp giới thiệu Visual Studio 2013). Tôi thậm chí đã cố gắng truyền EnableNuGetPackageRestore=truetham số - không may mắn. Tôi đang thiếu gì?


Bạn đang xây dựng giải pháp trong Visual Studio? Ngoài ra, mọi thứ có được đánh dấu trong Cài đặt Trình quản lý Gói trong phần Khôi phục Gói không? Bạn không cần thư mục .nuget nếu bạn đang xây dựng trong Visual Studio và sử dụng NuGet 2.7 trở lên.
Matt Ward

1
Không, tôi đang sử dụng phiên bản MsBuild ( msdn.microsoft.com/en-us/library/hh162058.aspx ) mới nhất từ ​​dòng lệnh. Đã cập nhật Nuget từ bên trong VS lên 2,8 - không may mắn.
UserControl

3
Riêng MSBuild sẽ không khôi phục và addin VS cũng vậy. Bạn cần kích hoạt khôi phục gói như @KMoraz đã nói, sau đó như Sumeshk đã nói, thư mục .nuget xuất hiện và các gói có thể được khôi phục. Đảm bảo rằng bạn kiểm tra .nuget vào kiểm soát nguồn.
Lex Li

Câu trả lời:


36

CẬP NHẬT với tài liệu NuGet chính thức mới nhất kể từ v3.3.0

Các Phương pháp Khôi phục Gói

NuGet cung cấp ba cách tiếp cận để sử dụng khôi phục gói .


Khôi phục gói tự động là cách tiếp cận được khuyến nghị của nhóm NuGet để Khôi phục gói trong Visual Studio và nó đã được giới thiệu trong NuGet 2.7. Bắt đầu với NuGet 2.7, phần mở rộng NuGet Visual Studio tích hợp vào các sự kiện xây dựng của Visual Studio và khôi phục các gói bị thiếu khi bắt đầu xây dựng. Tính năng này được bật theo mặc định, nhưng các nhà phát triển có thể chọn không tham gia nếu muốn.


Đây là cách nó hoạt động:

  1. Trên bản dựng dự án hoặc giải pháp, Visual Studio nêu ra một sự kiện rằng bản dựng đang bắt đầu trong giải pháp.
  2. NuGet phản hồi sự kiện này và kiểm tra các tệp package.config có trong giải pháp.
  3. Đối với mỗi tệp package.config được tìm thấy, các gói của nó được liệt kê và Kiểm tra tồn tại trong thư mục gói của giải pháp.
  4. Bất kỳ gói nào bị thiếu đều được tải xuống từ các nguồn gói được định cấu hình (và đã bật) của người dùng, tuân theo thứ tự của các nguồn gói.
  5. Khi các gói được tải xuống, chúng sẽ được giải nén vào thư mục gói của giải pháp.

Nếu bạn đã cài đặt Nuget 2.7+; điều quan trọng là chọn một phương pháp để> quản lý Khôi phục gói tự động trong Visual Studio.

Có hai phương pháp:

  1. (Nuget 2.7+): Visual Studio -> Công cụ -> Trình quản lý gói -> Cài đặt Trình quản lý gói -> Bật Khôi phục gói tự động
  2. (Nuget 2.6 trở xuống) Nhấp chuột phải vào một giải pháp và nhấp vào "Bật Khôi phục Gói cho giải pháp này".


Khôi phục gói dòng lệnh được yêu cầu khi xây dựng giải pháp từ dòng lệnh; nó đã được giới thiệu trong các phiên bản đầu tiên của NuGet, nhưng đã được cải tiến trong NuGet 2.7.

nuget.exe restore contoso.sln

Phương pháp khôi phục gói tích hợp MSBuild là cách triển khai Khôi phục gói ban đầu và mặc dù nó tiếp tục hoạt động trong nhiều trường hợp, nhưng nó không bao gồm toàn bộ các kịch bản được giải quyết bởi hai phương pháp còn lại.


63
Điều này không còn được khuyến nghị bởi nuget. Xem tài liệu. docs.nuget.org/docs/workflows/…
Owen Johnson

@OwenJohnson, tài liệu đó không có niên đại mà tôi có thể xem và tôi không thấy làm thế nào nó nói rằng nó không được đề xuất bây giờ? Tôi đang sử dụng VS2013 và nút đó dường như hoạt động tốt. Tôi không gặp sự cố được tham chiếu "Vì vậy, bạn đã nhấp vào" Bật Khôi phục gói Nuget "và bây giờ nội dung của bạn không được tạo. Các bước để khắc phục sự cố rất khó khăn nhưng ít đau đớn hơn với tập lệnh này". Github.com/owen2/ AutomaticPackageRestoreMigrationScript Có lẽ có một tài liệu khác giải thích thêm về điều này.
AnneTheAgile

5
Khôi phục gói tự động thay thế khôi phục tích hợp ms-build. Tài liệu hướng dẫn cách nâng cấp. Nếu bạn không gặp sự cố với phương pháp tích hợp msbuild, bạn không cần phải làm gì cả. Trong trường hợp đơn giản nhất, nó hoạt động, nhưng nếu bạn có máy chủ CI, tài liệu tham khảo dự án được chia sẻ hoặc một số điều kiện khác, bạn có thể dẫm phải một số loại mìn khó chịu và có các đường dẫn không chính xác hoặc các vấn đề khác.
Owen Johnson

1
Sử dụng câu trả lời này VÀ thực hiện theo hướng dẫn "xóa nội dung cũ" "Thực hiện di chuyển" tại docs.nuget.org/consume/package-restore/… , tôi đã có thể thành công.
granadaCoder

Có vẻ như mọi thứ đã thay đổi một lần nữa với NuGet 4 và tiêu chuẩn .net.
Owen Johnson

239

Nếu bạn đang sử dụng Visual Studio 2017 trở lên đi kèm với MSBuild 15 trở lên và các tệp .csproj của bạn ở định dạng mớiPackageReference , thì phương pháp đơn giản nhất là sử dụng Restoremục tiêu MSBuild mới .


Không ai thực sự trả lời được câu hỏi ban đầu, đó là "làm cách nào để các gói NuGet tự động khôi phục khi xây dựng từ dòng lệnh với MSBuild?" Câu trả lời là: trừ khi bạn đang sử dụng tùy chọn "Bật khôi phục gói NuGet" (tùy chọn này hiện không được dùng nữa theo tham chiếu này ), bạn không thể (nhưng hãy xem bên dưới). Nếu bạn đang cố gắng thực hiện các bản dựng tự động trên máy chủ CI, điều này thật tệ.

Tuy nhiên, có một cách hơi vòng vo để có được hành vi mong muốn:

  1. Tải xuống tệp thực thi NuGet mới nhất từ https://dist.nuget.org/win-x86-commandline/latest/nuget.exe và đặt nó ở đâu đó trong PATH của bạn. (Bạn có thể làm điều này như một bước xây dựng trước.)
  2. Chạy nuget restoresẽ tự động tải xuống tất cả các gói bị thiếu.
  3. Chạy msbuildđể xây dựng giải pháp của bạn.

Bên cạnh đó: mặc dù cách mới và được đề xuất để thực hiện khôi phục gói tự động liên quan đến việc kiểm soát phiên bản của bạn ít lộn xộn hơn, nó cũng khiến cho việc khôi phục gói dòng lệnh không thể thực hiện được trừ khi bạn vượt qua vòng tải xuống và chạy thêm nuget.exe. Phát triển?


Đã kết thúc với giải pháp tương tự (nhưng được đặt nuget.exevào / trunk / ext). Tiến một bước - lùi hai bước :(
UserControl

40
Đây phải là một cái máy chính xác, không phải cái được đánh dấu.
Woland

Điều này thực sự có vẻ hơi phản trực quan khi nói đến nó, nhưng bạn thực sự nhận được nhiều chức năng hơn để thêm các gói nuget cụ thể trở lại bằng cách sử dụng dòng lệnh. Giải pháp này đã làm việc cho tôi trong khi tự động khôi phục không thành công.
TGarrett,

2
Tôi đang sử dụng Jenkins và phải làm điều này, đó là một bước xây dựng đơn giản trước khi gọi msbuild - tệp loạt Windows là loại bước xây dựng và: cmd.exe / c "C: \ Program Files \ nuget \ nuget.exe" khôi phục < RelativePathToSln> .sln - Tôi đã thực hiện đường dẫn đến SLN như một thói quen / thủ tục đề phòng trường hợp nó không tìm thấy tệp sln.
Steve Radich-BitShop.com

1
Cách tiếp cận này phù hợp với tôi khi thiết lập khôi phục trên bản dựng Jenkins. Một chìa khóa quan trọng đối với tôi là NuGet.Config phải nằm trong cùng thư mục với tệp .SLN của tôi. Không có sự kết hợp nào của các vị trí tệp cấu hình khác, bao gồm việc chỉ định -ConfigFile trên dòng lệnh sẽ hoạt động.
Guerry,

56

Khôi phục gói tự động của Nuget là một tính năng của Visual Studio (bắt đầu từ năm 2013), không phải MSBuild. Bạn sẽ phải chạy nuget.exe restorenếu muốn khôi phục các gói từ dòng lệnh.

Bạn cũng có thể sử dụng tính năng Kích hoạt tính năng khôi phục gói Nuget, nhưng tính năng này không còn được khuyến khích bởi những người yêu thích nuget vì nó thực hiện các thay đổi xâm phạm đối với tệp dự án và có thể gây ra sự cố nếu bạn xây dựng các dự án đó trong một giải pháp khác.


2
Bạn cần chạy "nuget update -self" trước khi sử dụng lệnh khôi phục nếu phiên bản NuGet của bạn ít nhất là 2.7. NuGet của tôi là phiên bản 2.1 và không nhận dạng được lệnh "khôi phục" trước khi cập nhật.
Teknikaali,

2
"gây ra vấn đề nếu bạn xây dựng các dự án đó trong một giải pháp khác" Tôi chưa gặp phải bất kỳ vấn đề nào và chúng tôi có 3 giải pháp với hàng chục dự án mỗi giải pháp (nhiều giải pháp được chia sẻ trên các giải pháp). Có lẽ tôi đã gặp may?
Nelson Rothermel

@NelsonRothermel tình huống vấn đề đáng chú ý nhất có thể xảy ra là các dự án tham chiếu đến các hạt nhân được phân phối đến thư mục gói của giải pháp nước ngoài, có thể không có sẵn khi bạn xây dựng giải pháp.
Owen Johnson

2
@OwenJohnson Chúng tôi có một thư mục gói chung cho tất cả các giải pháp, vì vậy có lẽ đó là lý do tại sao chúng tôi không gặp sự cố.
Nelson Rothermel

17

Tôi đã mất một khoảng thời gian để tìm ra toàn cảnh và tôi muốn chia sẻ ở đây.

Visual Studio có hai cách tiếp cận để sử dụng khôi phục gói: Khôi phục gói tự động và khôi phục gói tích hợp MSBuild. 'Khôi phục gói tích hợp MSBuild' khôi phục các gói TRONG THỜI GIAN quá trình xây dựng có thể gây ra sự cố trong một số trường hợp. 'Khôi phục gói tự động' là phương pháp được nhóm NuGet đề xuất .

Có một số bước để làm cho 'Khôi phục gói tự động' hoạt động:

  1. Trong Visual Studio, Công cụ -> Tiện ích mở rộng và Cập nhật, Nâng cấp NuGet nếu có phiên bản mới hơn (Phiên bản 2.7 trở lên)

  2. Nếu bạn sử dụng TFS, trong thư mục .nuget của giải pháp của bạn, hãy xóa các tệp NuGet.exe và NuGet.targes. Sau đó chỉnh sửa NuGet.Config để không kiểm tra các gói NuGet:

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

    Nếu bạn đã kiểm tra trong thư mục gói của giải pháp thành TFS trước đó, hãy xóa thư mục và kiểm tra xóa xóa thư mục gói.

    Nếu bạn không sử dụng TFS, hãy xóa thư mục .nuget.

  3. Trong mỗi tệp dự án (.csproj hoặc .vbproj) trong giải pháp của bạn, hãy xóa dòng tham chiếu đến tệp NuGet.targets. Tham chiếu trông giống như sau:

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

    Loại bỏ dòng này trong mọi tệp dự án trong giải pháp của bạn.

  4. Trong menu Visual Studio, thông qua

    Công cụ -> Tùy chọn -> Trình quản lý gói -> Chung hoặc Công cụ -> Trình quản lý gói NuGet -> Cài đặt Trình quản lý gói

    vui lòng bật hai tùy chọn sau 1) 'Cho phép NuGet tải xuống các gói bị thiếu' 2) 'Tự động kiểm tra các gói bị thiếu trong quá trình xây dựng trong Visual Studio'

  5. Kiểm tra cấu hình khôi phục gói của bạn theo các bước sau

    • Lưu giải pháp của bạn và đóng Visual Studio
    • Xóa thư mục gói giải pháp của bạn
    • Khởi động Visual Studio, mở giải pháp của bạn và xây dựng lại nó.

1
Một trong những bước của bạn là xóa <Import Project = "$ (MSBuildToolsPath) \ Microsoft.CSharp.targets" />. Tại sao bạn lại làm vậy?
Sayed Ibrahim Hashimi

3
Tôi nghĩ rằng bạn đang nhầm lẫn đó là trong chính bản mẫu. Nếu không có nó, các tệp nguồn của bạn sẽ không được xây dựng.
Sayed Ibrahim Hashimi

3
Tôi nghĩ ý của anh ấy là nuget.targets thay vì Microsoft.CSharp.targets.
Owen Johnson

2
docs.nuget.org/docs/workflows/… <- Đây là tài liệu chính thức về những gì Ying đang cố gắng nói.
Owen Johnson

1
Ying nói đúng ... những gì mọi người đã bỏ qua là thực tế là các bản dựng Tích hợp liên tục tạo không gian làm việc tạm thời của riêng họ SAU các sự kiện trước khi xây dựng, lấy nguồn, và sau đó tham khảo NuGet. Đây là KHẮC PHỤC cho tự động hóa xây dựng TFS.
CZahrobsky

5

MSBuild 15 có một / t: tùy chọn khôi phục để thực hiện điều này. nó đi kèm với Visual Studio 2017.

Nếu bạn muốn sử dụng điều này, bạn cũng phải sử dụng PackageReference mới , có nghĩa là thay thế packages.configtệp bằng các phần tử như thế này (thực hiện điều này trong * .csproj):

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

Có một sự di chuyển tự động sang định dạng này nếu bạn nhấp chuột phải vào 'Tham khảo' (nó có thể không hiển thị nếu bạn vừa mở visual studio, xây dựng lại hoặc mở cửa sổ 'Quản lý gói NuGet cho giải pháp' và nó sẽ bắt đầu xuất hiện).


Bạn phải xem xét rằng tùy chọn khôi phục của msbuild có những điểm khác biệt nhỏ so với khôi phục nuget - ví dụ: xem github.com/NuGet/Home/issues/7651#issuecomment-500842049 .
Matthieu

4

Ian Kemp có câu trả lời (có một số điểm btw ..), điều này chỉ đơn giản là thêm một số thịt vào một trong các bước của anh ấy.

Lý do tôi kết thúc ở đây là máy của nhà phát triển đang xây dựng tốt, nhưng máy chủ xây dựng đơn giản là không kéo xuống các gói được yêu cầu (thư mục gói trống) và do đó quá trình xây dựng không thành công. Tuy nhiên, đăng nhập vào máy chủ xây dựng và xây dựng thủ công giải pháp đã hoạt động.

Để hoàn thành bước thứ hai trong số 3 bước của Ians (chạy khôi phục lại mã số ), bạn có thể tạo một mục tiêu MSBuild chạy lệnh thực thi để chạy lệnh khôi phục nuget, như bên dưới (trong trường hợp này nuget.exe nằm trong thư mục .nuget, thay vì trên đường dẫn), sau đó có thể chạy trong bước xây dựng TeamCity (có sẵn CI khác ...) ngay trước khi xây dựng giải pháp

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

Đối với bản ghi, tôi đã thử loại Á hậu "nuget installer" nhưng bước này bị treo trên các dự án web (hoạt động cho các dự án DLL và Windows)


1
Nếu bạn liên tục xây dựng từ một bộ mã mới (CI), đây là cách để thực hiện.
Jahmic

1
Tôi khá thích cách tiếp cận này vì nó đảm bảo rằng mỗi giải pháp / dự án dựa trên phiên bản của nuget mà nó được tạo ra. Trong thời gian thích hợp, điều này có thể trở nên quan trọng nếu bạn làm việc trong một công ty có các dự án cũ được tạo bằng các phiên bản cũ của nuget. Một nhà phát triển có thể duy trì các dự án như vậy mà không phải lo lắng về việc liệu nuget.exe trên toàn hệ thống có phá vỡ mọi thứ hay không vì mỗi dự án có "hương vị cục bộ" riêng của nuget.exe. Như một mẹo cuối cùng của nó đáng chú ý là với NuGet 3.x + chúng ta có thể khôi phục gói như vậy: nuget.exe khôi phục packages.config -PackagesDirectory path \ to \ gói
XDS

1
Vấn đề tôi gặp phải với cách tiếp cận này là bạn sẽ cần chỉnh sửa bất kỳ tệp dự án nào tiếp theo để thêm bước khôi phục. bạn có thể thêm hoạt động "InvokeProcess" trong TFS2012 hoặc hoạt động "NuGetRestore" trong mẫu bản dựng TFS2013 để bước này thực thi trên máy chủ bản dựng. đối với InvokeProcess, chuyển thuộc tính "SourcesDirectory" vào năm 2012. Trong TFS 2013, chỉ cần điền các giá trị theo yêu cầu. có rất nhiều blog về cách làm điều này.
Neville

3

Lưu ý rằng nếu bạn đang sử dụng TeamCity làm máy chủ xây dựng, bạn sẽ có bước "Trình cài đặt NuGet" mà bạn có thể sử dụng để khôi phục tất cả các gói trước bước xây dựng.


2

Có một packages.config tập tin với dự án, nó có chứa các chi tiết gói.

Ngoài ra còn có một thư mục .nuget chứa NuGet.exe và NuGet.targets . nếu bất kỳ tệp nào bị thiếu, nó sẽ không khôi phục gói bị thiếu và gây ra "bạn đang thiếu một chỉ thị đang sử dụng hoặc một tham chiếu hợp ngữ?" lỗi


2
Không có .nugetthư mục và không bao giờ có. Tất cả packages.configcác tệp trong các thư mục dự án đã được đặt sẵn.
UserControl

tôi nghĩ NuGet.exe và NuGet.targets sẽ tự động khôi phục tất cả các gói bị thiếu trong khi xây dựng ứng dụng và bạn bị mất các tệp NuGet.exe và NuGet.targets, điều đó gây ra lỗi
Sumeshk

Cảm ơn dù sao tôi đánh giá cao bất kỳ sự giúp đỡ!
UserControl

thư mục .nuget là thư mục do Visual Studio tạo, chỉ xuất hiện khi bạn bật tính năng tự động khôi phục gói. Sẽ rất hữu ích nếu có nuget.exe trong kho mã của bạn, vì bạn có thể tham chiếu nó trong các bản dựng của mình, cũng như nuget.config (đặc biệt nếu bạn cần lấy các gói từ nhiều kho).
MytyMyky

2

Đôi khi điều này xảy ra khi bạn có thư mục của gói mà bạn đang cố gắng khôi phục bên trong thư mục "gói" (tức là "Packages / EntityFramework.6.0.0 /" ) nhưng "DLL" không có bên trong nó (hầu hết các phiên bản điều khiển hệ thống tự động bỏ qua các tệp ".dll"). Điều này xảy ra bởi vì trước khi NuGet cố gắng khôi phục từng gói, nó sẽ kiểm tra xem các thư mục đã tồn tại chưa, vì vậy nếu nó tồn tại, NuGet giả định rằng "dll" nằm bên trong nó. Vì vậy, nếu đây là vấn đề đối với bạn, chỉ cần xóa thư mục mà NuGet sẽ khôi phục lại nó một cách chính xác.


1
Đối với VS 2015 và TFS, điều này sẽ giúp bạn khắc phục. Vấn đề sẽ là một tham chiếu không được giải quyết và thường vấn đề là gói nuget không được khôi phục vì thư mục cho gói đã tồn tại trong thư mục gói, nhưng gói chưa được mở rộng hoàn toàn đúng cách. (Chẳng hạn như thiếu thư mục lib phải chứa .dll.) Xóa toàn bộ thư mục cho gói trong các gói, sau đó nhấp chuột phải vào cấp giải pháp và chọn khôi phục gói.
Greg

1

Tôi đã gặp sự cố với các gói nuget không được bao gồm trong bản dựng hàng đêm theo tập lệnh tạo tệp sln bằng devenv.exe.

Tôi đã làm theo lời khuyên từ Microsoft và bước quan trọng là cập nhật cấu hình NuGet %AppData%/NuGetđể nó chứa:

<configuration>
    <packageRestore>
        <add key="automatic" value="True" />
    </packageRestore>
</configuration>

Vì vậy, tôi đã xác minh rằng khi bạn thay đổi cài đặt trong Visual Studio (hầu hết các câu trả lời ở đây) .... ở trên thực sự là những gì được thay đổi. "chìa khóa" còn lại là <add key = "enable" value = "False" />.
granadaCoder

0

Trong Visual Studio 2017 - Khi bạn biên dịch bằng IDE - Nó sẽ tải xuống tất cả các gói nuget bị thiếu và lưu trong thư mục "gói".

Nhưng trên máy xây dựng, việc biên dịch được thực hiện bằng cách sử dụng msbuild.exe. Trong trường hợp đó, tôi đã tải xuống nuget.exe và giữ nguyên đường dẫn.

Trong mỗi quá trình xây dựng trước khi thực thi msbuild.exe. Nó sẽ thực thi -> nuget.exe khôi phục NAME_OF_SLN_File (nếu chỉ có một tệp .SLN thì bạn có thể bỏ qua tham số đó)


0

Bạn cũng có thể dùng

Update-Package -reinstall

để khôi phục các gói NuGet trên Bảng điều khiển Quản lý Gói trong Visual Studio.


Đây không phải là câu trả lời cho câu hỏi này
TS
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.