Reputation: 4577
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:
.nuspec
is in the folder of the main project, ComputeSharp
, and has the following structure:<?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>
ComputeSharp
in Release mode, then open a cmd in the folder for that project, and run:nuget pack ComputeSharp.csproj -Prop Configuration=Release -IncludeReferencedProjects
.mustache
file being present in the right folder structure in the package, under the "content" directory):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
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
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