5

How do you copy a text file that has been included along with the DLLs within a NuGet package?

When I use my custom NuGet package in another solution (c:\dev\ for this example), the resulting file structure within c:\dev\package\projectId\lib\netstandard2.0\ has many DLLs and a text file, say file.txt. The DLLs are all copied upon building the solution, but the text file is left behind.

Within the .nuspec file, I originally included the file under <files><file src="foo\file.txt" target="lib\netstandard2.0"/></files>. The file.txt ends up in the packages folder when the NuGet package is restored, but it's not copied into the build directory.

Attempt 1: I tried using the contentFiles property within the nuspec file, since the nuspec reference points there a few times. I got nuget.exe pack command to work with this new property (i.e. no syntax errors), but there was no change in how the content (file.txt) was handled.

Attempt 2: I tried using a projectId.targets file. This uses a Target that has an ItemGroup that includes the file. Then, I tried using a Copy event, pointing to the destination folder as $(OutputPath).

It seems awfully hard to copy a file that is included in the package to the build directory, having to dive into MSBuild events and the like.

I'm at a loss here, and any pointers would be welcome.

Edits # 1:

I tried adding this section to the metadata, per a suggestion below:

<contentFiles> <files include="any\any\file.txt" buildAction="EmbeddedResource" /> </contentFiles>

This works in a small test case. The file.txt shows up nicely in both Visual Studio and in the build directory. Weirdly, it doesn't work in my main project using the same exact syntax (I'm using .NET Core 2.0 in both). Also, in NuGet Package Explorer, it shows up in the package contents when it's alone. But when I add something under <files><file src="lib\netstandard2.0\test.dll" target="lib\netstandard2.0"/></files>, it disappears from that view.

Edits # 2:

I think there's something else going on... Here is the .nuspec file from our main project. When I add a content file with the working suggestions below, it still doesn't show up (for either .NET Core 2.0 or .NET Framework 4.7.1). Is the .targets file messing this up somehow?

cezn
  • 81
  • 1
  • 5

2 Answers2

2

How to copy a text file from NuGet package during build of C# code that uses the package?

You should use contentFiles property and set copyToOutput="true" for the text file file.txt.

My test .nuspec file:

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
  <metadata>
    <id>MyTestCore</id>
    <version>5.0.0</version>
    <authors>TestContentFile</authors>
    <owners>TestContentFile</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Package Description</description>
    <contentFiles>
      <files include="any/any/file.txt" buildAction="content" flatten="true" copyToOutput="true"/>
    </contentFiles>
  </metadata>

  <files>
    <file src="contentFiles/any/any/file.txt" target="contentFiles/any/any" />
  </files>
</package>

After pack this .nuspec file, then add the nuget package to the project, build the project, the text file will copy to the build directory:

enter image description here

Check the update answer for the similar issue for some more details.

Leo Liu
  • 71,098
  • 10
  • 114
  • 135
  • Thanks for the pointer and the video! Presumably, the test package should only have `./any/any/file.txt`, correct? If I use the above .nuspec file, I get the following error: `Could not find a part of the path 'E:\source\repos\mzLib\contentFiles'.` When I deleted `contentFiles/` from the src attribute in ``, the test case works. – cezn Jul 06 '18 at 23:27
  • I get the same effect as I noted in **Edit # 1** above... this fix doesn't work for my main project, but at least the contentFile shows up in the NuGet Package Explorer for the test case. – cezn Jul 06 '18 at 23:36
0

You have to define build action to the file.

<contentFiles>
        <!-- Include Assets as Content -->
        <files include="foo\file.txt" buildAction="EmbeddedResource" />
</contentFiles>
  • Thanks for the pointer. This does work, but I'm still having trouble with it outside of a test case. I added to my question above with what I saw. – cezn Jul 06 '18 at 23:24