У меня аналогичная ситуация с внешними и внутренними источниками пакетов с проектами, на которые ссылаются более чем в одном решении. Я только что получил эту работу с одной из наших кодовых баз сегодня, и, похоже, она работает с рабочими станциями разработчиков и нашим сервером сборки. Приведенный ниже процесс имеет в виду этот сценарий (хотя нетрудно адаптироваться, чтобы иметь общую папку пакетов в другом месте).
- Кодовая база
- Проект А
- Проект Б
- Проект C
- Решения
- Решение 1
- Решение 2
- Решение 3
- Пакеты (общий для всех решений)
Обновленный ответ от NuGet 3.5.0.1484 с обновлением 3 для Visual Studio 2015
Этот процесс сейчас немного проще, чем когда я изначально занимался этим и думал, что пришло время обновить это. В общем, процесс тот же, только с меньшим количеством шагов. Результатом является процесс, который решает или обеспечивает следующее:
- Все, что необходимо внести в контроль исходного кода, видно и отслеживается в решении.
- При установке новых пакетов или обновлении пакетов с помощью диспетчера пакетов в Visual Studio будет использоваться правильный путь к репозиторию.
- После первоначальной настройки взлом файлов .csproj не будет
- Никаких модификаций рабочей станции разработчика (код готов к выпуску)
Есть некоторые потенциальные недостатки, о которых следует знать (я их еще не испытал, YMMV). См . Ответ и комментарии Бенола ниже.
Добавить NuGet.Config
Вам нужно создать файл NuGet.Config в корне папки \ Solutions \. Убедитесь, что это созданный вами файл в кодировке UTF-8. Если вы не знаете, как это сделать, используйте меню Visual Studio File-> New-> File, а затем выберите шаблон XML-файла. Добавьте в NuGet.Config следующее:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="$\..\Packages" />
</config>
</configuration>
Для параметра repositoryPath вы можете указать абсолютный или относительный путь (рекомендуется) с помощью токена $. Токен $ основан на том, где находится NuGet.Config (токен $ на самом деле относится к одному уровню ниже расположения NuGet.Config). Итак, если у меня есть \ Solutions \ NuGet.Config, и я хочу \ Solutions \ Packages, мне нужно будет указать $ \ .. \ Packages в качестве значения.
Затем вы захотите добавить к своему решению папку решения, которая называется что-то вроде «NuGet» (щелкните правой кнопкой мыши свое решение, «Добавить» -> «Новая папка решения»). Папки решения - это виртуальные папки, которые существуют только в решении Visual Studio и не создают фактическую папку на диске (и вы можете ссылаться на файлы из любого места). Щелкните правой кнопкой мыши папку решения «NuGet», затем «Добавить»> «Существующий элемент» и выберите \ Solutions \ NuGet.Config.
Причина, по которой мы делаем это, заключается в том, что это видно в решении и должно помочь убедиться, что оно должным образом привязано к элементу управления исходным кодом. Вы можете сделать этот шаг для каждого решения в вашей кодовой базе, которое участвует в ваших общих проектах.
Помещая файл NuGet.Config в \ Solutions \ над любыми файлами .sln, мы пользуемся тем фактом, что NuGet будет рекурсивно перемещаться по структуре папок вверх от «текущего рабочего каталога» в поисках файла NuGet.Config для использования. «Текущий рабочий каталог» означает здесь несколько разных вещей: один - это путь выполнения NuGet.exe, а другой - расположение файла .sln.
Переключение папки пакетов
Во-первых, я настоятельно рекомендую вам просмотреть все папки вашего решения и удалить все существующие папки \ Packages \ (сначала вам нужно закрыть Visual Studio). Это упрощает просмотр того, куда NuGet помещает вашу недавно настроенную папку \ Packages \, и гарантирует, что любые ссылки на неправильную папку \ Packages \ не будут работать и их можно будет исправить.
Откройте свое решение в Visual Studio и запустите Rebuild All. Игнорируйте все ошибки сборки, которые вы получите, это ожидается на данном этапе. Однако это должно запустить функцию восстановления пакета NuGet в начале процесса сборки. Убедитесь, что ваша папка \ Solutions \ Packages \ создана в нужном месте. Если нет, проверьте свою конфигурацию.
Теперь для каждого проекта в вашем решении вам нужно:
- Щелкните проект правой кнопкой мыши и выберите «Выгрузить проект».
- Щелкните проект правой кнопкой мыши и выберите Edit your-xxx.csproj.
- Найдите все ссылки на \ packages \ и обновите их в новом месте.
- Большинство из них будут ссылками на <HintPath>, но не все. Например, WebGrease и Microsoft.Bcl.Build будут иметь отдельные параметры пути, которые необходимо обновить.
- Сохраните .csproj, а затем щелкните проект правой кнопкой мыши и выберите «Обновить проект».
Как только все ваши файлы .csproj будут обновлены, запустите еще одну Rebuild All, и у вас больше не должно быть ошибок сборки, связанных с отсутствующими ссылками. На этом все готово, и теперь у NuGet настроено использование общей папки пакетов.
Начиная с NuGet 2.7.1 (2.7.40906.75) с VStudio 2012
Прежде всего, следует иметь в виду, что nuget.config не контролирует все параметры пути в системе пакетов nuget. Это было особенно сложно понять. В частности, проблема заключается в том, что msbuild и Visual Studio (вызывающие msbuild) не используют путь в nuget.config, а переопределяют его в файле nuget.targets.
Подготовка окружающей среды
Во-первых, я бы просмотрел папку вашего решения и удалил все существующие папки \ packages \. Это поможет обеспечить видимую установку всех пакетов в правильную папку и поможет обнаружить любые ссылки на неправильные пути во всех ваших решениях. Затем я хотел бы убедиться, что у вас установлено последнее расширение Nuget Visual Studio. Я также хотел бы убедиться, что у вас установлена последняя версия nuget.exe в каждом решении. Откройте командную строку, войдите в каждую папку $ (SolutionDir) \ .nuget \ и выполните следующую команду:
nuget update -self
Установка пути к общей папке пакета для NuGet
Откройте каждый $ (SolutionDir) \ .nuget \ NuGet.Config и добавьте следующее в раздел <configuration>:
<config>
<add key="repositorypath" value="$\..\..\..\Packages" />
</config>
Примечание. Вы можете использовать абсолютный или относительный путь. Имейте в виду, что если вы используете относительный путь с $, он относится к одному уровню ниже местоположения NuGet.Config (считаю, что это ошибка).
Установка пути к общей папке пакета для MSBuild и Visual Studio
Откройте каждый $ (SolutionDir) \ .nuget \ NuGet.targets и измените следующий раздел (обратите внимание, что для не-Windows есть еще один раздел под ним):
<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>
Обновить PackagesDir to be
<PackagesDir>$([System.IO.Path]::GetFullPath("$(SolutionDir)\..\Packages"))</PackagesDir>
Примечание: GetFullPath преобразует наш относительный путь в абсолютный путь.
Восстановление всех пакетов nuget в общую папку
Откройте командную строку и перейдите к каждому $ (SolutionDir) \ .nuget и выполните следующую команду:
nuget restore ..\YourSolution.sln
На этом этапе у вас должна быть одна папка \ packages \ в вашем общем расположении и ни одной папки ни в одной из папок вашего решения. Если нет, то проверьте свои пути.
Исправление ссылок на проекты
Откройте каждый файл .csproj в текстовом редакторе, найдите все ссылки на \ packages и обновите их до правильного пути. Большинство из них будут ссылками на <HintPath>, но не все. Например, WebGrease и Microsoft.Bcl.Build будут иметь отдельные параметры пути, которые необходимо обновить.
Создайте свое решение
Откройте свое решение в Visual Studio и начните сборку. Если он жалуется на отсутствующие пакеты, которые необходимо восстановить, не предполагайте, что пакет отсутствует и нуждается в восстановлении (ошибка может вводить в заблуждение). Это может быть неправильный путь в одном из ваших файлов .csproj. Прежде чем восстанавливать пакет, проверьте это.
Возникла ошибка сборки из-за отсутствующих пакетов?
Если вы уже убедились, что пути в ваших файлах .csproj верны, вы можете попробовать два варианта. Если это результат обновления кода из элемента управления исходным кодом, вы можете попробовать получить чистую копию, а затем создать ее. Это сработало для одного из наших разработчиков, и я думаю, что в файле .suo был артефакт или что-то подобное. Другой вариант - вручную принудительно восстановить пакет с помощью командной строки в папке .nuget рассматриваемого решения:
nuget restore ..\YourSolution.sln
$
перед относительным путем. Кроме того , ответ на ваш вопрос о NuGet.Config файлов здесь . Сначала он просматривает .nuget, затем все родительские каталоги, затем «глобальный» файл в вашем AppData: затем применяет их в ОБРАТНОМ порядке (что бы это ни значило).