Автоматичне відновлення пакунків NuGet не працює з MSBuild


111

Я намагаюся створити рішення з packagesвідсутнім вмістом (крім repositories.configвнутрішнього) за допомогою MSBuild 12.0. Я очікую, що він автоматично відновить усі відсутні пакети перед створенням, але це не так - MsBuild повідомляє про багато помилок:

"Ви пропускаєте директиву використання або посилання на збірку?"

NuGet Manager становить 2,7 (я бачу це у візуальній студії 2013 про поле). Я навіть намагався передати EnableNuGetPackageRestore=trueпараметр - не пощастило. Що я пропускаю?


Ви будуєте рішення в Visual Studio? Чи все відмічено в налаштуваннях менеджера пакунків у розділі «Відновлення пакета»? Вам не потрібна папка .nuget, якщо ви будуєте в Visual Studio і використовуєте NuGet 2.7 або вище.
Метт Уорд

1
Ні, я використовую останню версію MsBuild ( msdn.microsoft.com/en-us/library/hh162058.aspx ) з командного рядка. Оновлений Nuget зсередини VS до 2,8 - не щастить.
UserControl

3
MSBuild поодинці не відновить, а VS також додасть. Вам потрібно включити відновлення пакунків, як сказав @KMoraz, а потім, як сказав Сумешк, з'являється папка .nuget, і пакети можна відновити. Переконайтеся, що ви зареєстрували .увійти в управління джерелом.
Лекс Лі

Відповіді:


36

ОНОВЛЕНО з останньою офіційною документацією NuGet станом на v3.3.0

Підходи до відновлення пакету

NuGet пропонує три підходи до використання відновлення пакунків .


Автоматичне відновлення пакунків - це рекомендований підхід команди NuGet до відновлення пакунків у Visual Studio, і він був представлений у NuGet 2.7. Починаючи з NuGet 2.7, розширення NuGet Visual Studio інтегрується в події збирання Visual Studio і відновлює відсутні пакети, коли починається збірка. Ця функція включена за замовчуванням, але розробники можуть відмовитись за бажанням.


Ось як це працює:

  1. Під час створення проекту чи рішення рішення Visual Studio викликає подію, що збирання починається всередині рішення.
  2. NuGet реагує на цю подію і перевіряє наявність файлів пакети.config, що входять до рішення.
  3. Для кожного знайденого файла пакета.config його пакунки перераховуються та перевіряється на наявність у папці пакунків рішення.
  4. Будь-які відсутні пакети завантажуються з налаштованих (та увімкнених) джерел пакунків, дотримуючись порядку джерел пакунків.
  5. Коли завантажуються пакети, вони розпаковуються в папку пакунків рішення.

Якщо у вас встановлено Nuget 2.7+; важливо вибрати один метод> керування автоматичним відновленням пакунків у Visual Studio.

Доступні два методи:

  1. (Nuget 2.7+): Visual Studio -> Інструменти -> Менеджер пакетів -> Налаштування диспетчера пакунків -> Увімкнути автоматичне відновлення пакунків
  2. (Nuget 2.6 і нижче) Клацніть правою кнопкою миші рішення та натисніть "Увімкнути відновлення пакета для цього рішення".


Відновлення пакета командного рядка потрібно під час створення рішення з командного рядка; він був представлений у ранніх версіях NuGet, але був удосконалений у NuGet 2.7.

nuget.exe restore contoso.sln

Інтегрований підхід до відновлення пакету MSBuild є оригінальною реалізацією пакета відновлення, і хоча він продовжує працювати в багатьох сценаріях, він не охоплює повний набір сценаріїв, розглянутих двома іншими підходами.


63
Це більше не рекомендується nuget. Дивіться документи. docs.nuget.org/docs/workflows/…
Оуен Джонсон

@OwenJohnson, цей документ не датований тим, що я бачу, і я не бачу, як там сказано, що це не рекомендується зараз? Я на VS2013, і ця кнопка, здається, працює добре. У мене не було посилань на цю проблему: "Отже, ви натиснули" Увімкнути відновлення пакунків Nuget ", і тепер ваші речі не створюються. Кроки, щоб виправити це, є болючими, але менш болючими з цим сценарієм." Github.com/owen2/ AutomaticPackageRestoreMigrationScript Можливо, є ще один документ, який пояснює це далі.
AnneTheAgile

5
Автоматичне відновлення пакета замінює інтегроване відновлення для складання ms. Документ - це інструкція щодо оновлення. Якщо у вас немає проблем з інтегрованим методом msbuild, вам нічого не потрібно робити. У найпростіших випадках це працює, але якщо у вас є сервери CI, спільні посилання на проекти чи якісь інші умови, ви можете наступити на деякі противні міни та мати неправильні підказки чи інші проблеми.
Оуен Джонсон

1
Використовуючи цю відповідь І виконуючи інструкції "Вилучити старі речі" "Виконання міграції" на docs.nuget.org/consume/package-restore/… , я зміг знайти успіх.
granadaCoder

Схоже, що знову змінилися речі із стандартом NuGet 4 та .net.
Оуен Джонсон

239

Якщо ви використовуєте Visual Studio 2017 або новішої версії, яка постачається з MSBuild 15 або пізнішої версії, а ваші .csproj файли у новому PackageReferenceформаті , найпростішим методом є використання нової Restoreцілі MSBuild .


Ніхто насправді не відповів на початкове запитання, яке є "як мені отримати пакунки NuGet для автоматичного відновлення при побудові з командного рядка з MSBuild?" Відповідь: якщо ви не використовуєте параметр "Увімкнути відновлення пакета NuGet" (який тепер застарілий відповідно до цієї посилання ), ви не можете (але дивіться нижче). Якщо ви намагаєтеся зробити, наприклад, автоматизовані збірки на сервері CI, це не вдається.

Однак є трохи крутний спосіб отримати бажану поведінку:

  1. Завантажте останню версію NuGet з https://dist.nuget.org/win-x86-commandline/latest/nuget.exe і помістіть її десь у вашій PATH. (Це можна зробити як попередній крок.)
  2. Запустіть, nuget restoreякий автоматично завантажить усі відсутні пакети.
  3. Запустіть, msbuildщоб створити своє рішення.

Убік: хоча новий і рекомендований спосіб відновлення автоматичного відновлення пакунків передбачає менше затруднень у контролі вашої версії, він також робить неможливим відновлення пакета командного рядка, якщо ви не перескочите додатковий обруч завантаження та запуску nuget.exe. Прогрес?


Закінчено подібним розчином (але розміщено nuget.exeв / trunk / ext). Один крок вперед - два кроки назад :(
UserControl

40
Це має бути правильна відповідь, а не зазначена.
Воланд

Це дійсно здається трохи протилежним інтуїтивно зрозумілим, коли справа доходить до нього, але ви дійсно отримуєте більше функціональних можливостей, щоб додати конкретні нукет пакети за допомогою командного рядка. Це рішення працювало для мене, поки автоматичне відновлення не вдалося.
TGarrett

2
Я використовував Jenkins, і мені довелося це зробити, це був простий крок збирання перед викликом msbuild - пакетний файл Windows був типом кроку збірки та: cmd.exe / c "C: \ Program Files \ nuget \ nuget.exe" відновити < RelativePathToSln> .sln - я зробив шлях до SLN як звичку / процедуру на випадок, якщо не знайшов файл sln.
Стів Радіч-BitShop.com

1
Такий підхід працював для мене під час налаштування відновлення на складі Дженкінса. Одним з важливих моментів для мене було те, що NuGet.Config повинен знаходитися в тому ж каталозі, що і мій файл .SLN. Жодна комбінація інших конфігураційних файлів, включаючи вказівку -ConfigFile в командному рядку, не буде працювати.
Партиза

56

Автоматичне відновлення пакунків Nuget - це особливість Visual Studio (починаючи з 2013 року), а не MSBuild. Вам потрібно буде запустити, nuget.exe restoreякщо ви хочете відновити пакети з командного рядка.

Ви також можете скористатись функцією "Увімкнути відновлення Nuget Package Restore", але це не рекомендується, оскільки це вносить нав'язливі зміни у файли проектів і може спричинити проблеми, якщо ви будуєте ці проекти в іншому рішенні.


2
Перед використанням команди Restore потрібно запустити "nuget update -self", якщо версія NuGet не менше 2,7. Мій NuGet був версії 2.1 і не розпізнавав команду "відновити" перед оновленням.
Teknikaali

2
"викликає проблеми, якщо ви будуєте ці проекти в іншому рішенні" Я ще не стикався з жодними проблемами, і у нас є 3 рішення з десятками проектів кожен (багато спільного в різних рішеннях). Може, мені пощастило?
Нельсон Ротермель

@NelsonRothermel Найпомітнішою проблемною ситуацією, яка може статися, є проекти, що посилають нутризовані dll на папку пакетів закордонного рішення, яка може бути недоступною під час створення рішення.
Оуен Джонсон

2
@OwenJohnson У нас є одна загальна папка пакетів для всіх рішень, тому, ймовірно, тому ми не стикаємося з проблемами.
Нельсон Ротермель

17

Знадобилося трохи часу, щоб розібратися з цілою картиною, і я хотів би поділитися тут.

Visual Studio має два підходи до використання відновлення пакунків: автоматичне відновлення пакета та відновлення пакунків MSBuild-Integrated. 'Інтегральне відновлення пакунків MSBuild' відновлює пакети ПІД час процесу складання, які можуть спричинити проблеми в деяких сценаріях. Автоматичне відновлення пакунків - це рекомендований підхід командою NuGet.

Щоб зробити функцію "Автоматичне відновлення пакета", потрібно виконати кілька кроків:

  1. У Visual Studio, Інструменти -> Розширення та оновлення, Оновіть NuGet, якщо є новіша версія (Версія 2.7 або новіша версія)

  2. Якщо ви використовуєте TFS, в папці .nuget вашого рішення видаліть файли NuGet.exe і NuGet.targes. Потім відредагуйте NuGet.Config, щоб не перевіряти пакети NuGet:

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

    Якщо раніше ви перевірили папку пакунків для рішення в TFS, видаліть папку та перевірте, чи видалено папку пакунків.

    Якщо ви не використовуєте TFS, видаліть папку .nuget.

  3. У кожному файлі проекту (.csproj або .vbproj) у своєму рішенні видаліть рядок, що посилається на файл NuGet.targets. Посилання виглядає приблизно так:

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

    Видаліть цей рядок у кожному проектному файлі у своєму рішенні.

  4. У меню Visual Studio, або через

    Інструменти -> Параметри -> Менеджер пакунків -> Загальні або Інструменти -> Менеджер пакунків NuGet -> Налаштування диспетчера пакунків

    будь ласка, увімкніть наступні два варіанти 1) "Дозволити NuGet завантажувати відсутні пакети" 2) "Автоматично перевірити відсутні пакети під час збирання у Visual Studio"

  5. Перевірте конфігурацію відновлення пакета, виконавши наступні кроки

    • Збережіть своє рішення та закрийте Visual Studio
    • Видаліть папку пакетів вашого рішення
    • Запустіть Visual Studio, відкрийте рішення та відновіть його.

1
Один із ваших кроків - видалити <Import Project = "$ (MSBuildToolsPath) \ Microsoft.CSharp.targets" />. Навіщо ти це робив?
Сказав Ібрагім Хашімі

3
Думаю, ти помилився, що в самому шаблоні. Без нього ваші вихідні файли взагалі не будуватимуться.
Сказав Ібрагім Хашімі

3
Я думаю, що він мав на увазі nuget.targets замість Microsoft.CSharp.targets.
Оуен Джонсон

2
docs.nuget.org/docs/workflows/… <- Ось офіційні документи того, що намагався сказати Ін.
Оуен Джонсон

1
Ін є правильним ... те, що всі ігнорували, - це те, що безперервна інтеграція створює власну тимчасову робочу область ПІСЛЯ подій, що попередньо будують, отримують джерела, а потім задаються посиланнями NuGet. Це виправлення для автоматизації збирання TFS.
CZahrobsky

5

У MSBuild 15 є опція a / t: recovery, яка робить це. він поставляється з Visual Studio 2017.

Якщо ви хочете скористатися цим, вам також доведеться скористатися новим PackageReference , що означає замінити packages.configфайл такими елементами (зробіть це в * .csproj):

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

Автоматична міграція до цього формату відбувається, якщо ви клацніть правою кнопкою миші на "Список літератури" (вона може не відображатися, якщо ви щойно відкрили візуальну студію, відновіть або відкриєте вікно "Керувати пакетами NuGet для рішення", і воно почне відображатися).


Ви повинні врахувати, що опція відновлення msbuild має тонкі відмінності від відновлення nuget - див ., Наприклад, github.com/NuGet/Home/isissue/7651#issuecomment-500842049 .
Матьє

4

У Ian Kemp є відповідь (є кілька пунктів до цього дня). Це просто додати трохи м’яса в один із його кроків.

Причиною того, що я опинився тут, було те, що машини розробників нормально будувались, але сервер збирання просто не витягував необхідні пакети (порожня папка пакунків), і тому збірка провалювалася. Однак увійти на сервер збірки та створити рішення вручну.

Щоб виконати другий з 3-х крокових кроків Ians (запускаючи відновлення нугетів ), ви можете створити ціль MSBuild, що виконує команду exec, щоб виконати команду відновлення nuget, як показано нижче (у цьому випадку nuget.exe знаходиться в папці .nuget, а не на шляху), який потім можна виконати на етапі збирання TeamCity (інші CI доступні ...) безпосередньо перед створенням рішення

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

Для запису я вже спробував тип бігуна "nuget installer", але цей крок був висить у веб-проектах (працював для проектів DLL та Windows)


1
Якщо ви постійно будуєте з нового набору коду (CI), це шлях.
Джаміч

1
Мені подобається такий підхід, оскільки він гарантує, що кожне рішення / проект спирається на версію нюгету, з якою він був створений. Вчасно це може стати життєво важливим, якщо ви працюєте в компанії зі старими проектами, які були створені за допомогою старих версій nuget. Розробник може підтримувати подібні проекти, не переживаючи про те, чи не все-таки порушить систему nuget.exe, оскільки кожен проект має свій "локальний смак" nuget.exe. В якості останньої підказки варто зазначити, що за допомогою nuget 3.x + ми можемо відновити такі пакети: nuget.exe відновити пакети.config -PackagesDirectory path \ to \ пакети
XDS

1
Проблема, з якою я маю такий підхід, полягає в тому, що вам потрібно буде відредагувати будь-який наступний файл проекту, щоб додати крок відновлення. ви можете додати активність "InvokeProcess" в TFS2012 або активність "NuGetRestore" в шаблоні збірки TFS2013, щоб цей крок виконати на сервері збірки. для InvokeProcess, передайте атрибут "SourcesDirectory" у 2012 році. У TFS 2013 просто заповніть значення, як потрібно. Є багато блогів про те, як це зробити.
Невіл

3

Зауважте, що якщо ви використовуєте TeamCity як сервер збирання, ви отримуєте крок "NuGet Installer", який ви можете використовувати для відновлення всіх пакетів перед кроком збірки.


2

Існує файл package.config з проектом, він містить дані про пакет.

Також є папка .nuget, яка містить NuGet.exe і NuGet.targets . якщо в одному з файлів відсутній, він не відновить відсутній пакет і спричинить "Ви пропускаєте використання директиви або посилання на збірку?" помилка


2
.nugetПапки немає і ніколи не була. Усі packages.configфайли в папках проекту є на своєму місці.
UserControl

Я думаю, що NuGet.exe і NuGet.targets автоматично відновлять усі відсутні пакети під час створення програми, і ви втратили файли NuGet.exe і NuGet.targets, ось це спричинить помилки
Сумешк

Все одно дякую - я вдячний за будь-яку допомогу!
UserControl

папка .nuget - це папка, створена Visual Studio, яка з'являється лише тоді, коли ви включаєте автоматичне відновлення пакета. Корисно мати nuget.exe у своєму репортажі коду, оскільки ви можете посилатися на нього у своїх збірках, як і на nuget.config (особливо якщо вам потрібно отримати пакети з декількох репостів).
MytyMyky

2

Іноді це відбувається, коли у вас є папка пакета, яку ви намагаєтесь відновити всередині папки "пакети" (тобто "Packages / EntityFramework.6.0.0 /" ), але "DLL" не знаходяться всередині неї (більшість елементів управління версією системи автоматично ігнорують файли ".dll"). Це відбувається тому, що перш ніж NuGet намагається відновити кожен пакет, він перевіряє, чи папки вже існують, тому якщо він існує, NuGet припускає, що "dll" знаходиться всередині нього. Отже, якщо це проблема, ви просто видалите папку, що NuGet відновить її правильно.


1
Для VS 2015 та TFS це виправить. Проблема полягає в тому, що посилання не буде вирішено, і часто проблема полягає в тому, що пакет нута не відновлюється, оскільки папка для цього пакета вже існує в папці пакунків, але все-таки пакет не був розширений повністю належним чином. (Наприклад, відсутня папка lib, яка повинна містити .dll.) Видаліть всю папку для пакету з пакетів, а потім клацніть правою кнопкою миші на рівні рішення та виберіть відновлення пакетів.
Грег

1

У мене виникла проблема з тим, що пакунки з nuget не включаються в сценарій нічної збірки, який створює файл sln за допомогою devenv.exe.

Я дотримувався поради від Microsoft , і ключовим кроком було оновлення конфігурації NuGet %AppData%/NuGetтак, щоб вона містила:

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

Тож я переконався, що коли ви змінюєте налаштування в Visual Studio (більшість відповідей тут) .... вище сказане насправді те, що змінюється. інший "ключ" - <add key = "enable" value = "False" />.
granadaCoder

0

У Visual Studio 2017 - Коли ви компілюєте за допомогою IDE - він завантажить усі відсутні пакети нута та збереже у папці "пакети".

Але на складанні машини компіляція виконувалася за допомогою msbuild.exe. У такому випадку я завантажив nuget.exe і тримав шлях.

Під час кожного процесу збирання перед виконанням msbuild.exe. Він виконає -> nuget.exe відновить NAME_OF_SLN_File (якщо є лише один .SLN файл, ви можете проігнорувати цей параметр)


0

Ви також можете використовувати

Update-Package -reinstall

відновити пакети NuGet на консолі управління пакетами в Visual Studio.


Це не відповідь на це питання
TS
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.