Как добавить дополнительные файлы в пакет nuget в Visual Studio 2017

Недавно я перешел в Visual Studio 2017 Community Edition. Он имеет 2 приятных новых функций.

  • Вам не нужно явно указывать исходные файлы в csproj, это  делает это автоматически,
  • он может напрямую создавать пакеты nuget.

Я хочу упаковать свою DLL с открытым исходным кодом CodeFirstWebFramework в качестве пакета nuget. Помимо включения DLL, пакет должен включать в себя целое дерево каталогов других файлов (включая файлы .js,.tmpl,.css и .md).

Как сообщить Visual Studio, что я хочу, чтобы это дерево каталогов было включено в пакет?

Из какой информации, которую я нашел с обширным поиском, и игнорируя всю устаревшую информацию, связанную с добавлением файлов в csproj, все, что я мог найти, это разместить их в папке contentFiles, но это не похоже на работа.

Мой файл проекта выглядит следующим образом:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net45</TargetFramework>
    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
    <Authors>Nikki Locke</Authors>
    <Company>Trumphurst Ltd</Company>
    <Description>Easy to use web server for building web apps that use sql databases generated from c# classes</Description>
    <Copyright>2017 Trumphurst Ltd.</Copyright>
    <PackageProjectUrl>https://github.com/nikkilocke/CodeFirstWebFramework</PackageProjectUrl>
    <RepositoryUrl>https://github.com/nikkilocke/CodeFirstWebFramework</RepositoryUrl>
    <RepositoryType>Github</RepositoryType>
    <PackageTags>C# SQL Code First Web Server</PackageTags>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Markdig" Version="0.12.1" />
    <PackageReference Include="Mono.Data.Sqlite.Portable" Version="1.0.3.5" />
    <PackageReference Include="mustache-sharp" Version="0.2.10" />
    <PackageReference Include="MySql.Data" Version="6.9.9" />
    <PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
  </ItemGroup>

  <ItemGroup>
    <Reference Include="System.Net" />
    <Reference Include="System.Web" />
  </ItemGroup>

</Project>

Удивительно угадывая, что мне нужно делать из противоречивой и устаревшей информации в Интернете, я добавил следующее:

  <ItemGroup>
    <Content Include="contentFiles/**/*.*" copyToOutput="true">
      <IncludeInPackage>true</IncludeInPackage>
    </Content>
  </ItemGroup>

Теперь в файле .nupkg содержится содержимое папки contentFiles внутри него (в двух местах, папке content и папке contentFiles.

Однако, когда я устанавливаю пакет в другом проекте, файлы содержимого не отображаются, хотя они перечислены в файле project.assets.json в папке obj.

Ответ 1

Теперь я снова изменил файл проекта, поэтому теперь он читает:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net45</TargetFramework>
    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
    <Authors>Nikki Locke</Authors>
    <Company>Trumphurst Ltd</Company>
    <Description>Easy to use web server for building web apps that use sql databases generated from c# classes</Description>
    <Copyright>2017 Trumphurst Ltd.</Copyright>
    <PackageProjectUrl>https://github.com/nikkilocke/CodeFirstWebFramework</PackageProjectUrl>
    <RepositoryUrl>https://github.com/nikkilocke/CodeFirstWebFramework</RepositoryUrl>
    <RepositoryType>Github</RepositoryType>
    <PackageTags>C# SQL Code First Web Server</PackageTags>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Markdig" Version="0.12.1" />
    <PackageReference Include="Mono.Data.Sqlite.Portable" Version="1.0.3.5" />
    <PackageReference Include="mustache-sharp" Version="0.2.10" />
    <PackageReference Include="MySql.Data" Version="6.9.9" />
    <PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
  </ItemGroup>

  <ItemGroup>
    <Reference Include="System.Net" />
    <Reference Include="System.Web" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="contentFiles/**/*.*" copyToOutput="true">
      <IncludeInPackage>true</IncludeInPackage>
      <CopyToOutput>true</CopyToOutput>
      <BuildAction>Content</BuildAction>
      <copyToOutput>true</copyToOutput>
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

  <ItemGroup>
    <Compile Remove="Phone\**" />
    <EmbeddedResource Remove="Phone\**" />
    <None Remove="Phone\**" />
  </ItemGroup>

</Project>

ContentFiles теперь успешно скопированы в папку с тем же именем (т.е. contentFiles) в любом проекте, который загружает пакет NuGet - не уверен, какая директива работает, но одна из них.

Содержимое не будет автоматически скопировано в папку вывода проекта при компиляции, к сожалению - предложения приветствуются.

Ответ 2

Обертка в "Контент" и "IncludeInPackage" достаточно хороша, чтобы скопировать файлы (файлы) в пакет.

Ответ 3

Во-первых, имейте в виду, что вам нужно поместить файлы в папку content или contentFiles в зависимости от того, как на ваш пакет nuget ссылаются. Смотрите конец этого раздела.

По сути, если на файл nuget ссылается файл package.config, файлы из папки содержимого пакета nuget будут скопированы в ссылочный проект. Если на пакет nuget ссылается PackageReference в файле проекта, будут использоваться файлы из папки contentFiles в пакете. Рекомендуется включать оба.

Структуру папки contentFiles можно найти здесь. Можно указать язык и структуру для копируемых файлов.

Итак, в вашем случае:

<ItemGroup>
    <Content Include="contentFiles/**/*.*">
        <Pack>true</Pack>
        <PackagePath>contentFiles\any\any;content</PackagePath>
    </Content>
</ItemGroup>