Можно ли изменить расположение пакетов для 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 настройка для изменения каталога, в который загружаются все пакеты?


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 разместит пакеты в новом месте.


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>

Тоже самое. Конфигурация> 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) в папке решения.

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


Отлично! Работа для 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 и добавьте пакеты.

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


Перезапуск 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, а затем исправили все пути внутри, чтобы найти различные проекты и вуаля! Наша папка с пакетами оказалась там, где мы хотели.


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. Не забудьте заменить существующие ссылки в файлах проекта.

Это все еще так сегодня? Я имею в виду, мы не можем использовать абсолютное местоположение для новых добавленных пакетов? это решение для виртуальных дисков выглядит для меня обременительно
— 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>

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


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.