Sergio0694
Sergio0694

Reputation: 4577

How to setup a NuGet package to copy content files to output build directory?

NOTE: follow up from this question (now closed), as that one was too broad in scope, and the first part of that question, regarding .dlls, has been resolved, and this is a separate issue.

I'm working on a .NET Standard 2.0 project called ComputeSharp that I'd like to publish as a NuGet package, but I can't figure out how to have the package copy a content file to the output build directory of a project using it. Some info:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>ComputeSharp</id>
    ...
    <dependencies>
      <dependency id="SharpDX.Direct3D12" version="4.2.1-beta0-gab36f12303" />
      ...
    </dependencies>
    <contentFiles>
      <files include="..\ComputeSharp.Shaders\Renderer\Templates\*.mustache" buildAction="Content" copyToOutput="true" />
    </contentFiles>
  </metadata>
</package>
nuget pack ComputeSharp.csproj -Prop Configuration=Release -IncludeReferencedProjects
ComputeSharp.x.x.x.nupkg
├───rels
│   └───...
├───content
│   └───Renderer
│       └───Templates
│           └───ShaderTemplate.mustache
├───lib
│   └───netstandard2.0
│       ├───ComputeSharp.dll
│       ├───ComputeSharp.Graphics.dll
│       └───ComputeSharp.Shaders.dll
├───package
│   └───...
├───[Content_Types].xml
└───ComputeSharp.nuspec

PROBLEM: once I create a test project and install the NuGet package, I can build it just fine, but the whole Renderer\Templates\ShaderTemplate.mustache tree is not copied in the build directory, so as a result my lib can't load that file (as it's loaded relative to the path of the lib assembly).

I've read countless SO questions as well as the docs, and tried a bunch of combinations here (eg. setting ContentType="None" instead of "Content", but the result is always the same: the .mustache file is present in the package but it's not copied to the build directory of the project using it. Is there something else I need to do to just have the NuGet package recreate that tree + file in the output directory, when a project is built?

Thank you for your help!

Upvotes: 2

Views: 3695

Answers (2)

Eric Erhardt
Eric Erhardt

Reputation: 2466

You want to use the contentFiles folder and not content. See this blog NuGet ContentFiles Demystified.

You can also read Enable support for 'content' folder with PackageReference that explains why the content folder doesn't work with PackageReference.

Upvotes: 1

henon
henon

Reputation: 2508

I suggest embedding the files you need in the assembly with build action "Embedded resource". That way you don't have to rely on Nuget to install them. Instead, upon first usage, you can read them from the assembly and copy them into the file system or directly consume them. Here is how to read an embedded file from the assembly and copy it into the file system:

private void CopyEmbeddedResourceToFile(Assembly assembly, string resourceName, string filePath)
{
        var key = GetResourceKey(assembly, resourceName);
        using (Stream stream = assembly.GetManifestResourceStream(key))
        using (var file = new FileStream(filePath, FileMode.Create))
        {
            if (stream == null)
                throw new ArgumentException($"Resource name '{resourceName}' not found!");
            stream.CopyTo(file);
        }
}

Upvotes: 0

Related Questions