Можно ли изменить расположение пакетов для NuGet?

283

У меня есть следующее соглашение для большинства моих проектов:

/src
    /Solution.sln
    /SolutionFolder
        /Project1
        /Project2
        /etc..
/lib
    /Moq
        moq.dll
        license.txt
    /Yui-Compressor
        yui.compressor.dll
/tools
    /ILMerge
        ilmerge.exe

Вы заметите, что я не храню внешние библиотеки внутри исходной папки. Я также очень заинтересован в использовании NuGet, но не хочу, чтобы эти внешние библиотеки находились в исходной папке. Есть ли в NuGet настройка для изменения каталога, в который загружаются все пакеты?

TheCloudlessSky
источник
10
Да, да, да! Это именно та структура проекта, которую я использую (или почти очень), и я всегда задавался вопросом, может ли NuGet ее поддержать ...
Noldorin
Я подробно рассказал о том, как это сделать, с помощью следующего ответа: stackoverflow.com/a/19466173/564726 . Для правильной работы часто требуется удалить параметр solutionDir из команды восстановления.
BrutalDev
2
Я поставил .sln на тот же уровень, что и ваши папки верхнего уровня. :)
Ян Уорбертон

Ответы:

242

Теперь можно контролировать, в какую папку устанавливаются пакеты.

http://nuget.codeplex.com/workitem/215

Изменить: См. Комментарий Фила Хаака 10 декабря 2010 в 23:45 (в рабочем элементе / ссылка выше). Поддержка частично реализована в версии 1.0, но не документирована.

Согласно @dfowler: Добавьте файл nuget.config рядом с решением с помощью этого:

<settings>
<repositoryPath>{some path here}</repositoryPath>
</settings>

Существует пакет nuget для создания переопределения папки пакета.

Обновление для версии 2.1

Как прокомментировал Азат, сейчас есть официальная документация о том, как контролировать расположение пакетов. В примечаниях к выпуску 2.1 указывается следующая конфигурация в файле nuget.config (описание допустимых мест для размещения файлов конфигурации и описание работы иерархической модели конфигурации см. В примечаниях к выпуску):

<configuration>
  <config>
    <add key="repositoryPath" value="C:\thePathToMyPackagesFolder" />
  </config>
  ... 
</configuration>

Это изменит папку пакетов для уровня конфигурации, в который вы помещаете файл (решение, если вы поместите его в каталог решения, проект в каталог проекта и т. Д.). Обратите внимание, что в примечаниях к выпуску указано:

[...] если у вас есть папка с пакетами под корнем вашего решения, вам нужно будет удалить ее, прежде чем NuGet разместит пакеты в новом месте.

PHeiberg
источник
5
На самом деле это возможно с помощью вышеуказанного файла конфигурации. Причина, по которой это было подчеркнуто, заключается в том, что у нас пока не было рабочего процесса, позволяющего включить это через пользовательский интерфейс и другие средства, поэтому ожидаем некоторую причудливость.
Дэвидфоул
5
См. Reviewboard.nupack.com/r/131 для полного описания @dfowler того, как работает nuget.config. Например, допустимый nuget.config будет выглядеть следующим образом: <settings> <repositoryPath> lib </ repositoryPath> </ settings>
Ли Гарольд,
5
docs.nuget.org/docs/release-notes/nuget-2.1 См. параграф «Укажите местоположение папки пакетов»
Азат
1
Я могу подтвердить, что новый способ ведения дел в 2.1+ не работает. И есть ошибки об этом на codeplex: nuget.codeplex.com/workitem/2921 .
Дело
5
Вторая версия работает для меня, я использую последнюю версию NuGet, и теперь два решения могут использовать одно и то же репо. Я думаю, что это может не сработать некоторым людям, потому что они могут использовать абсолютные пути? Кажется, что абсолютный и относительный путь имеет значение.
Чаба Тот
63
  1. Создан файл с именем «nuget.config».
  2. Добавил этот файл в папку с моими решениями

это не работает для меня:

<configuration>
  <config>
    <add key="repositoryPath" value="..\ExtLibs\Packages" />
  </config>
  ... 
</configuration>

это сработало для меня:

<?xml version="1.0" encoding="utf-8"?>
<settings>
  <repositoryPath>..\ExtLibs\Packages</repositoryPath>
</settings>
ShaneKm
источник
Тоже самое. Конфигурация> config не работает, но настройки> repositoryPath сделали.
Джин Реддик
Работает только второе решение: docs.nuget.org/docs/reference/nuget-config-file
cheesemacfly
15
Это зависит от версии NuGet, которую вы используете.
Бронумский
1
Обратите внимание, что относительные пути относятся к решению, поэтому, если ваши проекты находятся на разных уровнях, оно не будет работать.
Девять Хвостов
2
Это прекрасно работает для VIsual Studio 2013, но если я использую Visual Studio 2015, он все равно устанавливает пакеты в папке пакетов рядом с файлом sln,
fhnaseer
40

Хорошо, ради кого-то еще, читающего этот пост - вот что я понимаю из множества ответов выше:

  1. Файл nuget.config в .nuget папки по отношению к этой папке. Это важно, потому что, если ваша новая папка похожа на «../Packages», она будет помещена туда, где она всегда есть из коробки. Поскольку @ bruce14 утверждает, что вместо этого вы должны сделать '../../Packages'

  2. Я не смог получить последнюю версию nuget (2.8.5) для поиска папки с пакетами за пределами стандартного местоположения без включения восстановления пакетов. Поэтому, как только вы включите восстановление пакета, в файл nuget.config внутри папки .nuget необходимо добавить следующее:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      ...
      <config>
        <add key="repositoryPath" value="..\..\Packages" />
      </config>
      ...
    </configuration>
  3. (Это важно). Если вы вносите ЛЮБЫЕ изменения в расположение папки пакета внутри файлов nuget.config, вы должны перезапустить Visual Studio или закрыть / перезагрузить решение, чтобы изменения вступили в силу.

Роберт Петц
источник
5
Поверь мне, твое очко № 3 спасло мой день. Я был сумасшедшим с прошлых 3 часов, пока я не прочитал ваш пункт № 3 : '(Спасибо
тебе
24

Решение для Nuget 3.2 в Visual Studio 2015:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <config>
        <add key="repositoryPath" value="../lib" />
    </config>
</configuration>

Использование косой черты для родительской папки. Сохраните файл выше (nuget.config) в папке решения.

Ссылка доступна здесь

phuongnd
источник
Отлично! Работа для Visual Studio 2015 и Nuget версии 3.2.0.10516
Anon Dev
Похоже, вы имели в виду наклонную черту влево ... но если решение для окон, возможно, эта косая черта превратится в обратную, или, возможно, прямая косая черта была опечаткой и должна измениться на обратную.
Джерард ONeill
Я нахожусь в 2015 году, и мне нужно использовать .. \ .. \ пакеты, чтобы он поднялся на одну папку.
Rhyous
1
../libЭто косая черта, а не обратная. Что ты имеешь в виду?
jpmc26
Да, это точно слеш. Обновленный ответ
phuongnd
15

Решение, предложенное в примечаниях к выпуску 2.1, не работает "из коробки". Они забыли упомянуть, что есть код:

internal string ResolveInstallPath()
{
    if (!string.IsNullOrEmpty(this.OutputDirectory))
    {
        return this.OutputDirectory;
    }
    ISettings settings = this._configSettings;

    ...
}

что мешает ему работать. Чтобы это исправить, вам нужно изменить файл NuGet.targets и удалить параметр «OutputDirectory»:

    <RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)"  $(RequireConsentSwitch)</RestoreCommand>

Так что теперь, если вы добавите конфигурацию 'repositoryPath' где-нибудь в NuGet.config (см. Примечания к выпуску для описания допустимых мест для размещения файлов конфигурации), он восстановит все пакеты в одном месте, но ... Ваш .csproj по-прежнему содержит подсказки для сборок, записанных в виде относительных путей ...

Я до сих пор не понимаю, почему они пошли не так, как надо, вместо того, чтобы изменить PackageManager, чтобы он добавлял пути подсказок относительно PackagesDir. Именно так я делаю вручную, чтобы иметь разные местоположения пакетов локально (на моем рабочем столе) и в агенте сборки.

<Reference Include="Autofac.Configuration, Version=2.6.3.862, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
  <Private>True</Private>
  <HintPath>$(PackagesDir)\Autofac.2.6.3.862\lib\NET40\Autofac.Configuration.dll</HintPath>
</Reference>
Дмитрий Наумов
источник
1
Ты абсолютно прав. В моей компании мы фактически используем версию NuGet, которую мы модифицировали сами, которая делает именно то, что вы описываете, то есть она добавляет HintPaths относительно каталога Packages, а не относительно расположения файла проекта. Это прекрасно работает. К сожалению, мы так и не удосужились попытаться внести изменения, внесенные в NuGet, в официальную версию, но, может быть, пришло время сделать это сейчас ...
afrischke
1
@afrischke: было бы здорово, если бы ты мог это сделать. Спасибо. Есть идеи, когда это может произойти?
СГТЦ
11

В дополнение к ответу Shane Kms, если вы активировали Восстановление пакета Nuget, вы измените файл NuGet.config, расположенный в папке .nuget, следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <repositoryPath>..\..\ExtLibs\Packages</repositoryPath>
</configuration>

Обратите внимание на лишнее «.. \», так как оно возвращается из папки .nuget, а не из папки решения.

пользователь
источник
9

Ни один из этих ответов не работал для меня (Nuget 2.8.6) из-за отсутствия некоторых советов, постараюсь добавить их здесь, так как это может быть полезно для других.

После прочтения следующих источников:
https://docs.nuget.org/consume/NuGet-Config-Settings
https://github.com/NuGet/Home/issues/1346
Оказывается , что

  1. Для правильной работы Install-Package с другим repositoryPath вам необходимо использовать forward косые черты, потому что они используют объект Uri для анализа местоположения.
  2. Без $ в начале он все еще игнорировал мои настройки.
  3. NuGet кеширует конфигурационный файл, поэтому после внесения изменений необходимо перезагрузить решение / VS.
  4. У меня также была странная проблема при использовании команды NuGet.exe для установки этой опции, так как она изменила мой глобальный NuGet.exe в AppData \ Roaming \ NuGet и начала восстанавливать пакеты там (так как этот файл имеет более высокий приоритет, просто догадываюсь).

Например

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <solution>
    <add key="disableSourceControlIntegration" value="true" />
  </solution>
  <config>
    <add key="repositorypath" value="$/../../../Common/packages" />
  </config>
</configuration>

Вы также можете использовать команду NuGet, чтобы убедиться, что синтаксис будет правильным:

NuGet.exe config -Set repositoryPath=$/../../../Common/packages -ConfigFile NuGet.Config
Роман Бадиорный
источник
8

Для проектов .NET Core и Visual Studio 2017 я смог восстановить все пакеты по относительному пути, предоставив следующую конфигурацию:

<configuration>
  <config>
    <add key="globalPackagesFolder" value="lib" />
  </config>
  ... 
</configuration>

Исходя из моего опыта, папка lib была создана на том же уровне, где был найден Nuget.config, независимо от того, где находился файл sln. Я проверил, и поведение одинаково для восстановления командной строки и восстановления Visual Studio 2017

Кирилл Чилингарашвили
источник
Я попробовал это. Я установил globalPackagesFolderключ к папке пакета моего проекта. Я пытался добавить один пакет с dotnet add package MyPackage. nuget.exeзагрузил всю структуру 83 пакетов .NET в эту папку. Это не то, что я хотел. Я просто хотел, чтобы мой единственный MyPackage находился в моей локальной, управляемой исходным кодом папке пакета.
Уоллес Келли
НЕ ДЕЛАЙ ЭТОГО! Это довольно быстро переполнит ваш жесткий диск, так как все пакеты фреймворка будут загружаться каждый раз, когда вы создаете новое приложение.
Алаа Масуд
1
согласно этому ответу на другой вопрос: stackoverflow.com/a/47407399/4572240 «respositoryPath используется для проектов packages.config, globalPackagesFolder используется для проектов PackageReference».
Siderite Zackwehdex
7

Конфиг-файл в принятом ответе у меня работает в VS2012. Впрочем, для меня это только работает тогда, когда я делаю следующее:

  1. Создать новый проект в VS.
  2. Выход VS - это кажется важным.
  3. Скопируйте файлы конфигурации в папку проекта.
  4. Перезапустите VS и добавьте пакеты.

Если я буду следовать этим шагам, я смогу использовать общую папку пакета.

Harald
источник
Перезапуск VS - единственный способ заставить это работать. Угадай, менеджер пакетов кеширует это.
Филипп
6

Чтобы изменить путь для проектов, использующих PackageReference вместо packages.config, необходимо использовать globalPackagesFolder

С https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file

globalPackagesFolder (проекты, использующие только PackageReference)

Расположение папки глобальных пакетов по умолчанию. По умолчанию используется% userprofile% .nuget \ packages (Windows) или ~ / .nuget / packages (Mac / Linux). Относительный путь можно использовать в специфичных для проекта файлах nuget.config. Этот параметр переопределяется переменной среды NUGET_PACKAGES, которая имеет приоритет.

repositoryPath (только packages.config)

Расположение для установки пакетов NuGet вместо папки $ (Solutiondir) / packages по умолчанию. Относительный путь можно использовать в специфичных для проекта файлах nuget.config. Этот параметр переопределяется переменной среды NUGET_PACKAGES, которая имеет приоритет.

<config>
    <add key="globalPackagesFolder" value="c:\packageReferences" />
    <add key="repositoryPath" value="c:\packagesConfig" />
</config>

Я поместил Nuget.config рядом с моим файлом решения, и это сработало.

Мэнни
источник
5

Еще один маленький кусочек, который я только что обнаружил. (Это может быть настолько просто, что некоторые не упоминали об этом, но это было важно для моего решения.) Папка «packages» заканчивается в той же папке, что и ваш файл .sln.

Мы переместили наш файл .sln, а затем исправили все пути внутри, чтобы найти различные проекты и вуаля! Наша папка с пакетами оказалась там, где мы хотели.

NickNuke
источник
4

ОБНОВЛЕНИЕ для VS 2017:

Похоже, что люди в команде Nuget наконец-то сами начали использовать Nuget, что помогло им найти и исправить несколько важных вещей. Так что теперь (если я не ошибаюсь, так как все еще не мигрировал на VS 2017) ниже не нужно больше. Вы должны иметь возможность установить «repositoryPath» в локальную папку, и она будет работать. Даже вы можете вообще его оставить, так как по умолчанию место восстановления перемещено из папок решения на уровень компьютера. Снова - я все еще не проверял это самостоятельно

VS 2015 и ранее

Просто подсказка к другим ответам (именно этим ):

Расположение папки пакета NuGet можно изменить с помощью конфигурации, но VisualStudio по-прежнему ссылается на сборки в этой папке:

<HintPath>..\..\..\..\..\..\SomeAssembly\lib\net45\SomeAssembly.dll</HintPath>

Чтобы обойти это (до лучшего решения), я использовал команду subst для создания виртуального диска, который указывает на новое расположение папки Packages:

subst N: C:\Development\NuGet\Packages

Теперь при добавлении нового пакета NuGet ссылка на проект использует его абсолютное местоположение:

<HintPath>N:\SomeAssembly\lib\net45\SomeAssembly.dll</HintPath>

Примечание:

  1. Такой виртуальный диск будет удален после перезагрузки, поэтому убедитесь, что вы справились с ним
  2. Не забудьте заменить существующие ссылки в файлах проекта.
Kamarey
источник
Это все еще так сегодня? Я имею в виду, мы не можем использовать абсолютное местоположение для новых добавленных пакетов? это решение для виртуальных дисков выглядит для меня обременительно
batmaci
Да, все еще случай, поскольку ничего не изменилось
Камарей
2
Я на самом деле предпочитаю относительный путь - таким образом, нет никакого конфликта в управлении исходным кодом, если разные разработчики имеют разные корневые местоположения для кода.
17
Интересно, почему вы не можете сделать <HintPath>$(SolutionDir)\packages\SomeAssembly\lib\net45\SomeAssembly.dll</HintPath> вместо того, чтобы использоватьsubst
Винод Шривастав
Я хотел, чтобы все пакеты были в одном месте, а не в
одном
3

Просто обновление с Nuget 2.8.3. Чтобы изменить расположение установленных пакетов, я включил восстановление пакетов из щелчка правой кнопкой мыши. Отредактировал NuGet.Config и добавил следующие строки:

  <config>
    <add key="repositorypath" value="..\Core\Packages" />
  </config>

Затем пересобрал решение, он загрузил все пакеты в нужную папку и автоматически обновил ссылки.

Амарнат Чаттерджи
источник