Как сообщить nuget добавить файлы ресурсов пакета в виде ссылок, а не копировать их в каталог проекта

Вступление (как упаковать ресурсы в пакет nuget)

Чтобы упаковать некоторые файлы ресурсов в пакет nuget, то, что обычно будет делать, следующее.

Поместите все файлы ресурсов в каталог content\ пакета nuget. Это будет указано следующей строкой в ​​файле .nuspec:

<files>
  <file src="Project\bin\Release\script.js" target="content\js\script.js" />
<files>

Теперь, когда этот пакет nuget устанавливается в AnotherProject, появляется следующая файловая структура:

Solution.sln
packages\Project.1.0.0\content\js\script.js  // the original resource file
AnotherProject\js\script.js                  // a physical copy 
AnotherProject\AnotherProject.csproj         // <Content /> tag (see below)

Во время установки пакета AnotherProject.csproj был добавлен тег:

<Content Include="js\script.js" />

и это для физической копии исходного ресурса (который находится в каталоге packages\).

Актуальная проблема (как упаковать ресурсы в пакет nuget как ссылку)

Моя цель - не иметь физическую копию файла ресурсов в каталоге AnotherProject, а скорее "ссылку" на исходный ресурс в каталоге packages\. В csproj это должно выглядеть так:

<Content Include="packages\Project.1.0.0\content\js\script.js">
  <Link>js\script.js</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

Решение грубой силы, которое я предпочел бы избежать

Теперь, обходное решение "сделай это трудным путем", о котором я могу думать:

  • не помещать файлы ресурсов в content\, чтобы они не добавлялись автоматически,
  • запись Install.ps1 script, которая взломает структуру файла csproj и добавит необходимую часть XML вручную,

Это, однако, имеет следующие недостатки:

  • всем моим пакетам nuget нужна те же script часть в Install.ps1,
  • при установке моих пакетов в Visual Studio будет неприятная "перезагрузка проекта".

Ответ 1

Так как NuGet в настоящее время не поддерживает это, вы можете использовать PowerShell или использовать пользовательскую цель MSBuild.

PowerShell

  • Оставьте свои ресурсы за пределами каталога Content в вашем пакете NuGet (как вы уже сказали).
  • Добавьте ссылку на файл с помощью PowerShell в install.ps1.

Вы можете избежать запроса перезагрузки проекта, если вы используете объектную модель Visual Studio (EnvDTE). Я бы посмотрел на Project.ProjectItems.AddFromFile(...), чтобы узнать, работает ли это для вас.

Цель MSBuild

  • NuGet поддерживает добавление оператора импорта в проект, который указывает на файл MSBuild.props и/или .targets. Таким образом, вы можете поместить свои ресурсы в каталог tools вашего пакета NuGet и ссылаться на него из файла MSBuild.props/.targets.

Как правило, пользовательские .props и .targets используются для настройки процесса сборки. Однако они являются только файлами проекта MSBuild, поэтому вы можете добавлять элементы для своих ресурсов в эти файлы проектов.

Обратите внимание, что .props импортируются в начале файла проекта, когда установлен пакет NuGet, в то время как .targets импортируются в конце проекта.

Настройка NuGet

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