Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 696
Nikki Locke Avatar asked Jun 12 '17 11:06

Nikki Locke


People also ask

How do I add a NuGet file to Visual Studio?

You first have to tell Visual Studio about the location of your package, and then you can add it to a project. What most people do is go into the NuGet Package Manager and add the local folder as a source (menu Tools → Options → NuGet Package Manager → Package Sources).

How do I create a Nupkg file in Visual Studio 2017?

You can configure Visual Studio to automatically generate the NuGet package when you build the project. In Solution Explorer, right-click the project and choose Properties. In the Package tab, select Generate NuGet package on build.


2 Answers

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.

like image 56
Nikki Locke Avatar answered Oct 12 '22 05:10

Nikki Locke


First, please be aware that you need to put your files either into a content or contentFiles folder depending on how you NuGet package is referenced. See the end of this section.

Basically, if a NuGet project is referenced by package.config file, the files from the content folder of the NuGet package will be copied to the referencing project. If the NuGet package is referenced by PackageReference in the project file, the files from the contentFiles folder within the package will be used. It is recommended to include both.

The structure of the contentFiles folder can be found here. It is possible to specify the language and the framework for the files to be copied.

So in your case:

<ItemGroup>     <Content Include="contentFiles/**/*.*">         <Pack>true</Pack>         <PackagePath>contentFiles\any\any;content</PackagePath>     </Content> </ItemGroup> 
like image 44
Fabian Avatar answered Oct 12 '22 03:10

Fabian