Автоматическое восстановление пакета NuGet не работает с MSBuild

111

Я пытаюсь создать решение с packagesотсутствующим содержимым (кроме repositories.configвнутреннего) с помощью MSBuild 12.0. Я ожидаю, что он автоматически восстановит все отсутствующие пакеты перед сборкой, но это не так - MsBuild сообщает о множестве ошибок:

"вам не хватает директивы using или ссылки на сборку?"

NuGet Manager - 2,7 (я вижу это в окне о Visual Studio 2013). Я даже пытался передать EnableNuGetPackageRestore=trueпараметр - не повезло. Что мне не хватает?

UserControl
источник
Вы создаете решение в 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, и пакеты можно будет восстановить. Убедитесь, что вы отметили .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 реагирует на это событие и проверяет файлы packages.config, включенные в решение.
  3. Для каждого найденного файла packages.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-build. В документе есть инструкция по обновлению. Если у вас нет проблем с методом, интегрированным с msbuild, ничего делать не нужно. В простейших случаях это работает, но если у вас есть серверы CI, общие ссылки на проекты или некоторые другие условия, вы можете наступить на неприятные наземные мины и получить неверные пути подсказки или другие проблемы.
Оуэн Джонсон,
1
Используя этот ответ И выполняя инструкции «Удалить старые вещи» «Выполнение миграции» на docs.nuget.org/consume/package-restore/… , я смог добиться успеха.
granadaCoder
Похоже, что все снова изменилось с NuGet 4 и стандартом .net.
Оуэн Джонсон
239

Если вы используете Visual Studio 2017 или более поздней версии,PackageReference которая поставляется с MSBuild 15 или более поздней версии , и ваши файлы .csproj находятся в новом формате , самый простой способ - использовать новую Restoreцель MSBuild .


На самом деле никто не ответил на исходный вопрос: «Как мне заставить пакеты NuGet автоматически восстанавливаться при сборке из командной строки с помощью MSBuild?» Ответ: если вы не используете параметр «Включить восстановление пакета NuGet» (который теперь не рекомендуется в соответствии с этой ссылкой ), вы не можете (но см. Ниже). Если вы пытаетесь выполнить, например, автоматическую сборку на сервере CI, это отстой.

Однако есть несколько окольный способ добиться желаемого поведения:

  1. Загрузите последнюю версию исполняемого файла NuGet с https://dist.nuget.org/win-x86-commandline/latest/nuget.exe и поместите его где-нибудь в свой путь. (Вы можете сделать это перед сборкой.)
  2. Запустите, nuget restoreкоторый автоматически загрузит все недостающие пакеты.
  3. Беги, msbuildчтобы построить свое решение.

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

Ян Кемп
источник
Закончилось аналогичным решением (но помещено nuget.exeв / trunk / ext). Один шаг вперед - два шага назад :(
UserControl
40
Это должен быть правильный ответ, а не отмеченный.
Воланд
Это действительно кажется немного интуитивно понятным, когда дело доходит до этого, но вы действительно получаете больше возможностей для добавления определенных пакетов nuget обратно с помощью командной строки. Это решение сработало для меня, пока автоматическое восстановление не удалось.
TGarrett
2
Я использовал Jenkins и должен был сделать это, это был простой шаг сборки перед вызовом msbuild - пакетный файл Windows был типом шага сборки и: cmd.exe / c "C: \ Program Files \ nuget \ nuget.exe" restore < RelativePathToSln> .sln - Я сделал путь к SLN как привычку / процедуру на случай, если он не нашел файл sln.
Стив Радич-BitShop.com
1
Этот подход сработал для меня при настройке восстановления сборки Jenkins. Одним из важных моментов для меня было то, что NuGet.Config должен находиться в том же каталоге, что и мой файл .SLN. Никакая комбинация других расположений файла конфигурации, включая указание -ConfigFile в командной строке, не будет работать.
Guerry
56

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

Вы также можете использовать функцию «Включить восстановление пакета Nuget», но это больше не рекомендуется разработчиками nuget, поскольку она вносит навязчивые изменения в файлы проекта и может вызвать проблемы, если вы создадите эти проекты в другом решении.

Оуэн Джонсон
источник
2
Вам необходимо запустить nuget update -self перед использованием команды restore, если ваша версия NuGet не ниже 2.7. Мой NuGet был версии 2.1 и не распознавал команду «восстановить» перед обновлением.
Teknikaali
2
«вызывает проблемы, если вы собираете эти проекты в другом решении». Я еще не сталкивался с какими-либо проблемами, и у нас есть 3 решения с десятками проектов в каждом (многие из которых используются в разных решениях). Может мне повезло?
Нельсон Ротермель
@NelsonRothermel Наиболее заметная проблемная ситуация, которая может возникнуть, - это проекты, ссылающиеся на библиотеки DLL, доставляемые nuget, в папку пакетов стороннего решения, которая может быть недоступна при создании решения.
Оуэн Джонсон,
2
@OwenJohnson У нас есть одна общая папка с пакетами для всех решений, поэтому, вероятно, поэтому мы не столкнулись с проблемами.
Нельсон Ротермел,
17

Мне потребовалось время, чтобы понять всю картину, и я хотел бы поделиться здесь.

В Visual Studio есть два подхода к использованию восстановления пакетов: автоматическое восстановление пакета и восстановление пакета, интегрированное с MSBuild. «MSBuild-Integrated Package Restore» восстанавливает пакеты ВО ВРЕМЯ процесса сборки, что может вызвать проблемы в некоторых сценариях. Команда 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 есть параметр / t: restore для этого. он поставляется с 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/issues/7651#issuecomment-500842049 .
Matthieu
4

У Иэна Кемпа есть ответ (есть кое-что, между прочим ...), это просто добавить немного мяса к одному из своих шагов.

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

Чтобы выполнить второй из трех шагов Ians (выполнение восстановления nuget ), вы можете создать цель MSBuild, запустив команду exec для запуска команды восстановления nuget, как показано ниже (в этом случае nuget.exe находится в папке .nuget, а не на пути), который затем можно запустить на этапе сборки TeamCity (доступны другие CI ...) непосредственно перед сборкой решения.

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

Для справки, я уже пробовал бегун типа «установщик nuget», но этот шаг зависал в веб-проектах (работал для проектов DLL и Windows).

Fetchez la vache
источник
1
Если вы постоянно строите из свежего набора кода (CI), это правильный путь.
Jahmic
1
Мне нравится этот подход, потому что он гарантирует, что каждое решение / проект зависит от версии nuget, с которой он был создан. В свое время это может оказаться жизненно важным, если вы работаете в компании со старыми проектами, созданными с использованием старых версий nuget. Разработчик может поддерживать такие проекты, не беспокоясь о том, сломает ли общесистемный файл nuget.exe, потому что каждый проект имеет свой собственный "локальный вкус" nuget.exe. В качестве последнего совета стоит отметить, что с помощью nuget 3.x + мы можем восстанавливать пакеты следующим образом: nuget.exe restore packages.config -PackagesDirectory path \ to \ packages
XDS
1
Проблема, с которой я столкнулся с этим подходом, заключается в том, что вам нужно будет отредактировать любой последующий файл проекта, чтобы добавить шаг восстановления. вы можете добавить действие «InvokeProcess» в TFS2012 или действие «NuGetRestore» в шаблон сборки TFS2013, чтобы этот шаг выполнялся на сервере сборки. для InvokeProcess передайте атрибут «SourcesDirectory» в 2012 году. В TFS 2013 просто введите необходимые значения. есть много блогов о том, как это сделать.
Невилл
3

Обратите внимание, что если вы используете TeamCity в качестве сервера сборки, вы получаете шаг «Установщик NuGet», который можно использовать для восстановления всех пакетов перед шагом сборки.

Деян
источник
2

С проектом есть файл packages.config , он содержит детали пакета.

Также есть папка .nuget, которая содержит NuGet.exe и NuGet.targets . если какой-либо один из файлов отсутствует, он не восстановит отсутствующий пакет и вызовет "вам не хватает директивы using или ссылки на сборку?" ошибка

Sumeshk
источник
2
Папки нет .nugetи не было. Все packages.configфайлы в папках проекта на месте.
UserControl
Я думаю, что NuGet.exe и NuGet.targets автоматически восстановят все отсутствующие пакеты при создании приложения, и вы потеряли свои файлы NuGet.exe и NuGet.targets, что вызывает ошибки
Sumeshk
В любом случае спасибо - я ценю любую помощь!
UserControl
папка .nuget - это папка, созданная Visual Studio, которая появляется только при включении автоматического восстановления пакета. Полезно иметь nuget.exe в репозитории вашего кода, так как вы можете ссылаться на него в своих сборках, как и на nuget.config (особенно если вам нужно получить пакеты из нескольких репозиториев).
MytyMyky
2

Иногда это происходит, когда папка с пакетом, который вы пытаетесь восстановить, находится внутри папки «packages» (например, «Packages / EntityFramework.6.0.0 /» ), но «DLL» не находятся внутри нее (большая часть системы контроля версий системы автоматически игнорируют файлы ".dll"). Это происходит потому, что перед попыткой восстановления каждого пакета NuGet проверяет, существуют ли уже папки, поэтому, если он существует, NuGet предполагает, что «dll» находится внутри него. Поэтому, если это проблема для вас, просто удалите папку, и NuGet восстановит ее правильно.

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

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

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

<configuration>
    <packageRestore>
        <add key="automatic" value="True" />
    </packageRestore>
</configuration>
PaulG
источник
Итак, я проверил, что когда вы меняете настройки в Visual Studio (большинство ответов здесь) .... на самом деле изменяется именно то, что указано выше. другой «ключ» - это <add key = "enabled" value = "False" />.
granadaCoder,
0

В Visual Studio 2017 - при компиляции с использованием IDE - он загрузит все недостающие пакеты nuget и сохранит их в папке «пакеты».

Но на сборочной машине компиляция производилась с помощью msbuild.exe. В этом случае я загрузил nuget.exe и сохранил путь.

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

Дэвид
источник
0

Вы также можете использовать

Update-Package -reinstall

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

MovGP0
источник
Это не ответ на этот вопрос
TS