Tôi có một tình huống tương tự với các nguồn gói bên ngoài và bên trong với các dự án được tham chiếu trong nhiều hơn một giải pháp. Tôi vừa mới làm việc với một trong những cơ sở mã của chúng tôi ngày hôm nay và dường như nó đang làm việc với các máy trạm của nhà phát triển và máy chủ xây dựng của chúng tôi. Quá trình dưới đây có kịch bản này trong tâm trí (mặc dù không khó để thích nghi để có thư mục gói chung khác ở đâu).
- Cơ sở mã hóa
- Dự án A
- Dự án B
- Dự án C
- Các giải pháp
- Giải pháp 1
- Giải pháp 2
- Giải pháp 3
- Các gói (đây là gói chung được chia sẻ bởi tất cả các giải pháp)
Câu trả lời được cập nhật kể từ NuGet 3.5.0.1484 với Visual Studio 2015 Update 3
Quá trình này bây giờ dễ dàng hơn một chút so với khi tôi ban đầu giải quyết vấn đề này và nghĩ rằng đã đến lúc cập nhật nó. Nói chung, quá trình là như nhau chỉ với ít bước hơn. Kết quả là một quá trình giải quyết hoặc cung cấp như sau:
- Mọi thứ cần được cam kết để kiểm soát mã nguồn đều hiển thị và được theo dõi trong giải pháp
- Cài đặt gói mới hoặc cập nhật gói bằng Trình quản lý gói trong Visual Studio sẽ sử dụng đường dẫn kho lưu trữ chính xác
- Sau cấu hình ban đầu, không hack các tệp .csproj
- Không có sửa đổi của máy trạm dành cho nhà phát triển (Mã được xây dựng sẵn sàng khi thanh toán)
Có một số nhược điểm tiềm năng cần lưu ý (Tôi chưa trải nghiệm chúng, YMMV). Xem câu trả lời và ý kiến của Benol bên dưới.
Thêm NuGet.Config
Bạn sẽ muốn tạo tệp NuGet.Config trong thư mục gốc của thư mục \ Solutions \. Đảm bảo đây là tệp được mã hóa UTF-8 mà bạn tạo, nếu bạn không chắc chắn cách thực hiện việc này, hãy sử dụng menu Tệp của Visual Studio-> Mới-> Tệp, sau đó chọn mẫu Tệp XML. Thêm vào NuGet.Config như sau:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="$\..\Packages" />
</config>
</configuration>
Đối với cài đặt repositoryPath, bạn có thể chỉ định đường dẫn tuyệt đối hoặc đường dẫn tương đối (được khuyến nghị) bằng cách sử dụng mã thông báo $. Mã thông báo $ dựa trên vị trí của NuGet.Config (Mã thông báo $ thực sự có liên quan đến một cấp dưới đây vị trí của NuGet.Config). Vì vậy, nếu tôi có \ Solutions \ NuGet.Config và tôi muốn \ Solutions \ Gói tôi sẽ cần chỉ định $ \ .. \ Gói làm giá trị.
Tiếp theo, bạn sẽ muốn thêm Thư mục Giải pháp cho giải pháp của mình được gọi là "NuGet" (Nhấp chuột phải vào giải pháp của bạn, Thêm-> Thư mục Giải pháp mới). Thư mục giải pháp là các thư mục ảo chỉ tồn tại trong giải pháp Visual Studio và sẽ không tạo thư mục thực trên ổ đĩa (và bạn có thể tham chiếu các tệp từ bất kỳ đâu). Nhấp chuột phải vào thư mục giải pháp "NuGet" của bạn, sau đó Thêm-> Mục hiện có và chọn \ Solutions \ NuGet.Config.
Lý do chúng tôi đang làm điều này là để nó hiển thị trong giải pháp và sẽ giúp đảm bảo rằng nó được cam kết đúng với kiểm soát mã nguồn của bạn. Bạn có thể muốn thực hiện bước này cho từng giải pháp trong cơ sở mã đang tham gia với các dự án được chia sẻ của bạn.
Bằng cách đặt tệp NuGet.Config trong \ Solutions \ trên bất kỳ tệp .sln nào, chúng tôi đang lợi dụng thực tế là NuGet sẽ điều hướng đệ quy cấu trúc thư mục từ "thư mục làm việc hiện tại" đang tìm kiếm tệp NuGet.Config để sử dụng. "Thư mục làm việc hiện tại" có nghĩa là một vài thứ khác nhau ở đây, một là đường dẫn thực thi của NuGet.exe và thứ hai là vị trí của tệp .sln.
Chuyển qua thư mục gói của bạn
Trước tiên, tôi thực sự khuyên bạn nên xem qua từng thư mục giải pháp của mình và xóa mọi thư mục \ Gói \ tồn tại (trước tiên bạn cần đóng Visual Studio). Điều này giúp dễ dàng hơn để xem NuGet đang đặt thư mục \ Gói \ mới được cấu hình của bạn và đảm bảo rằng mọi liên kết đến thư mục \ Gói \ sẽ bị lỗi và sau đó có thể được sửa.
Mở giải pháp của bạn trong Visual Studio và khởi động Rebuild All. Bỏ qua tất cả các lỗi xây dựng bạn sẽ nhận được, điều này được dự kiến tại thời điểm này. Điều này sẽ khởi động tính năng khôi phục gói NuGet khi bắt đầu quá trình xây dựng. Xác minh rằng thư mục \ Solutions \ Gói \ của bạn đã được tạo ở vị trí bạn muốn. Nếu không, hãy xem lại cấu hình của bạn.
Bây giờ, đối với mỗi dự án trong giải pháp của bạn, bạn sẽ muốn:
- Nhấp chuột phải vào dự án và chọn Unload Project
- Nhấp chuột phải vào dự án và chọn Chỉnh sửa của bạn-xxx.csproj
- Tìm bất kỳ tài liệu tham khảo nào cho \ gói \ và cập nhật chúng lên vị trí mới.
- Hầu hết trong số này sẽ là tài liệu tham khảo <HintPath>, nhưng không phải tất cả. Ví dụ: WebGreas và Microsoft.Bcl.Build sẽ có các cài đặt đường dẫn riêng biệt cần được cập nhật.
- Lưu .csproj và sau đó nhấp chuột phải vào dự án và chọn Tải lại dự án
Khi tất cả các tệp .csproj của bạn đã được cập nhật, hãy khởi động một Rebuild All khác và bạn sẽ không còn lỗi xây dựng nào về các tham chiếu bị thiếu. Tại thời điểm này, bạn đã hoàn tất và bây giờ có cấu hình NuGet để sử dụng thư mục Gói chia sẻ.
Kể từ NuGet 2.7.1 (2.7.40906.75) với VStudio 2012
Trước tiên, điều cần lưu ý là nuget.config không kiểm soát tất cả các cài đặt đường dẫn trong hệ thống gói nuget. Điều này đặc biệt khó hiểu để tìm ra. Cụ thể, vấn đề là msbuild và Visual Studio (gọi msbuild) không sử dụng đường dẫn trong nuget.config mà thay vào đó là ghi đè nó trong tệp nuget.target.
Chuẩn bị môi trường
Đầu tiên, tôi sẽ đi qua thư mục của giải pháp của bạn và xóa tất cả \ gói \ thư mục tồn tại. Điều này sẽ giúp đảm bảo rằng tất cả các gói được cài đặt rõ ràng vào thư mục chính xác và để giúp khám phá mọi tham chiếu đường dẫn xấu trong các giải pháp của bạn. Tiếp theo, tôi sẽ đảm bảo bạn đã cài đặt tiện ích mở rộng Visual Studio mới nhất. Tôi cũng sẽ đảm bảo rằng bạn đã cài đặt nuget.exe mới nhất vào mỗi giải pháp. Mở một dấu nhắc lệnh và đi vào từng thư mục $ (SolutionDir) \ .nuget \ và thực hiện lệnh sau:
nuget update -self
Đặt đường dẫn thư mục gói chung cho NuGet
Mở mỗi $ (SolutionDir) \ .nuget \ NuGet.Config và thêm phần sau vào phần <configure>:
<config>
<add key="repositorypath" value="$\..\..\..\Packages" />
</config>
Lưu ý: Bạn có thể sử dụng một đường dẫn tuyệt đối hoặc một đường dẫn tương đối. Hãy ghi nhớ, nếu bạn đang sử dụng một đường dẫn tương đối với $ mà nó có liên quan đến một cấp dưới vị trí của NuGet.Config (tin rằng đây là một lỗi).
Đặt đường dẫn thư mục gói chung cho MSBuild và Visual Studio
Mở mỗi $ (SolutionDir) \ .nuget \ NuGet.target và sửa đổi phần sau (lưu ý rằng đối với người không dùng Windows, có một phần khác bên dưới nó):
<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>
Cập nhật các góiDir để được
<PackagesDir>$([System.IO.Path]::GetFullPath("$(SolutionDir)\..\Packages"))</PackagesDir>
Lưu ý: GetFullPath sẽ giải quyết đường dẫn tương đối của chúng ta thành một đường dẫn tuyệt đối.
Khôi phục tất cả các gói nuget vào thư mục chung
Mở một dấu nhắc lệnh và goto mỗi $ (SolutionDir) \ .nuget và thực hiện lệnh sau:
nuget restore ..\YourSolution.sln
Tại thời điểm này, bạn nên có một thư mục \ gói \ ở vị trí chung và không có trong bất kỳ thư mục giải pháp nào. Nếu không, sau đó xác minh đường dẫn của bạn.
Sửa chữa tài liệu tham khảo dự án
Mở mọi tệp .csproj trong trình soạn thảo văn bản và tìm bất kỳ tham chiếu nào đến \ gói và cập nhật chúng theo đúng đường dẫn. Hầu hết trong số này sẽ là tài liệu tham khảo <HintPath>, nhưng không phải tất cả. Ví dụ: WebGreas và Microsoft.Bcl.Build sẽ có các cài đặt đường dẫn riêng biệt cần được cập nhật.
Xây dựng giải pháp của bạn
Mở giải pháp của bạn trong Visual Studio và khởi động một bản dựng. Nếu nó phàn nàn về các gói bị thiếu cần được khôi phục, đừng cho rằng gói bị thiếu và cần được khôi phục (lỗi có thể gây hiểu nhầm). Nó có thể là một đường dẫn xấu trong một trong các tệp .csproj của bạn. Kiểm tra trước khi khôi phục gói.
Có một lỗi xây dựng về các gói bị thiếu?
Nếu bạn đã xác minh rằng các đường dẫn trong tệp .csproj của bạn là chính xác, thì bạn có hai tùy chọn để thử. Nếu đây là kết quả của việc cập nhật mã của bạn từ kiểm soát mã nguồn thì bạn có thể thử kiểm tra một bản sao sạch và sau đó xây dựng nó. Điều này đã làm việc cho một trong những nhà phát triển của chúng tôi và tôi nghĩ rằng có một tạo tác trong tệp .suo hoặc một cái gì đó tương tự. Tùy chọn khác là buộc thủ công khôi phục gói bằng cách sử dụng dòng lệnh trong thư mục .nuget của giải pháp được đề cập:
nuget restore ..\YourSolution.sln
$
phía trước con đường tương đối. Ngoài ra, câu trả lời cho câu hỏi của bạn về các tệp NuGet.Config có ở đây . Đầu tiên, nó tìm trong .nuget, sau đó trong tất cả các thư mục mẹ, sau đó vào tệp 'toàn cầu' trong AppData của bạn: sau đó áp dụng chúng theo thứ tự REVERSE (bất kể điều đó có nghĩa là gì).