Prevent duplicating files in NuGet content and contentFiles folders
Found updated documentation describing this in detail at MSBuild targets for NuGet.
By default, everything gets added to the root of the
content
andcontentFiles\any\<target_framework>
folder within a package and preserves the relative folder structure, unless you specify a package path:<Content Include="..\win7-x64\libuv.txt"> <Pack>true</Pack> <PackagePath>content\myfiles\</PackagePath> </Content>
If you want to copy all your content to only a specific root folder(s) (instead of
content
andcontentFiles
both), you can use the MSBuild propertyContentTargetFolders
, which defaults to "content;contentFiles" but can be set to any other folder names. Note that just specifying "contentFiles" inContentTargetFolders
puts files undercontentFiles\any\<target_framework>
orcontentFiles\<language>\<target_framework>
based onbuildAction
.
If you only want to output the file to the build output (content
only copies the file to the output directory but does cause it to be set as copy to output directory item), you can use a completely different approach by creating an msbuild file that will be included in the project.
You can do this by putting both the file - say test.jpg
into the tools
folder (you could also use build
) and add a Your.Package.Id.targets
file to the build
folder (the name being the package id of your package with .targets
as extension) with the following content:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Content Include="$(MSBuildThisFileDirectory)..\tools\test.jpg">
<Link>test.jpg</Link>
<Visible>false</Visible>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
</Project>
This target will be automatically imported into the project files regardless of which "style" of NuGet reference is used (packages.config
, PackageReference
) and should be backwards compatible to older versions of VS as long as they support NuGet and ToolsVersion 4.0
.
The Link
metadata denotes where in the output / publish directories the file will end up. You could set it to e.g. defaultContent\images\foo.jpg
to create a nested structure and rename the file. (you could even use MSBulid variables to use some of the referencing project's configuration). The Visible
metadata prevents the solution explorer from showing the full relative path to the file, which could end up in lots of nested ..
nodes. The CopyToPublishDirectory
applies to .NET Core / ASP.NET Core apps or SDK-based projects using the Publish
target for publishing.
Note that you can set the Inclue
-path to anything depending on where in your package the file is. You can also use wildcards (but then set Link
to %(Filename)%(Extension)
)