How do you add additional files to a nuget package in Visual Studio 2017

Nikki Locke picture Nikki Locke · Jun 12, 2017 · Viewed 12k times · Source

I recently moved to Visual Studio 2017 Community Edition. It has 2 nice new features

  1. You don't need to explicitly include your source files in the csproj, it does this automatically,
  2. it can build nuget packages directly.

I want to package up my open source CodeFirstWebFramework DLL as a nuget package. As well as including the DLL, the package has to include a whole directory tree of other files (including .js, .tmpl, .css and .md files).

How do I tell Visual Studio that I want this directory tree included in the package?

From what information I have found with extensive searching, and ignoring all the out of date information that involves adding files to the csproj, all I could find was to place them in a contentFiles folder, but this does not seem to work.

My project file looks like this:

<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>

Wildly guessing what I might need to do from the conflicting and out-of-date information on the web, I have added the following:

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

Now the .nupkg file has the contents of the contentFiles folder insider it (in two places, a content folder, and a contentFiles folder.

However, when I install the package in another project, the content files do not appear, although they are listed in the project.assets.json file in the obj folder.

Answer

Nikki Locke picture Nikki Locke · Jun 20, 2017

I have now changed my project file again, so it now reads:

<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>

The contentFiles are now successfully copied into a folder of the same name (i.e. contentFiles) in any project that downloads the NuGet package - not sure which directive worked, but one of them did.

The content is not automatically copied to the project's output folder on compile, unfortunately - suggestions welcome.