简体   繁体   中英

Nuget package contentFiles not copied to .NET Core project

I'm trying to extract content files from a Nuget package to a project referencing my package.

Based on Justin Emgarten's comment

Packages.config projects use the content folder

Project.json/PackageReference/NETCore SDK projects use the contentFiles folder

So ok great, I created a .NET Core 2.1 Console Application project and followed the NuGet ContentFiles Demystified blog post which was written in 2016 at the time of project.json but should still work nowadays.

I created an image at c:\\dev\\ContentFilesExample\\contentFiles\\any\\any\\images\\dnf.png then created a c:\\dev\\ContentFilesExample\\ContentFilesExample.nuspec file and copy pasted the content:

<?xml version="1.0"?>
<package>
    <metadata minClientVersion="3.3.0">
        <id>ContentFilesExample</id>
        <version>1.0.0</version>
        <authors>nuget</authors>    <!-- The NuGet team authored this package -->
        <owners>nuget</owners>      <!-- The NuGet team owns this package -->
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>A content v2 example package.</description>
        <tags>contentv2 contentFiles</tags>
        <!-- Build actions for items in the contentFiles folder -->
        <contentFiles>
            <!-- Include Assets as Content -->
            <files include="**/images/*.*" buildAction="EmbeddedResource" />
        </contentFiles>
    </metadata>
</package>

Then I generated the Nuget package with the command nuget pack ContentFilesExample.nuspec and opened it using Nuget Package Explorer

在此处输入图片说明

Great my picture is there as expected.

And now the final non-working step. I install this Nuget package in my .NET Core 2.1 project but the image is missing. No trace of the image in the root directory of my project, neither in the obj folder nor in the bin folder.

I tried to close and re-open visual studio as stated in some comments somewhere but that didn't solve the issue.

I also tried to change my .NET Core project style to PackageReference but again, this didn't solve the issue

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp2.1</TargetFramework>
        <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="ContentFilesExample" Version="1.0.0" />
    </ItemGroup>

    <ItemGroup>
        <None Update="appsettings.json">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </None>
    </ItemGroup>

</Project>

So what am I doing wrong? Are content files in Nuget packages really supported by .NET Core?

Thank you

I ended up on this question after hours and hours of googling for a solution, so I decided to write another answer to make things clear because MS docs suck

  1. <files> element in .nuspec file is for the packer . It tells nuget which files to pack (if there are no <files> element in your nuspec - nuget will use the directory naming convention)
  2. <contentFiles> element is for the consumer - it tells how and when to extract the files.
  3. If you want a file to appear in your project after installing - you have to pack it with a target that says contentFiles/any/any where "any/any" part tells nuget it's for ANY language and ANY framework.
  4. (optional) if you also want this file to work with the old nuget mode, that uses packages.config - you have to pack it again, 2nd time, this time - to "content" folder, so older consumers can still use it.

nuspec

  <metadata>
   ...
    <contentFiles>
      <files include="**/myfile.cs" />
    </contentFiles>
  </metadata>
  <files>
      <file src="myfile.cs" target="contentFiles\any\any" /> <!-- this is for new format -->
      <file src="myfile.cs" target="content" /> <!-- this is for the old format -->
  </files>

PS. Some more details in my blog post here

nupkg should have contentFiles/ directory:
nupkg

Install to netcore project:
在此输入图像描述

It won't be a loose file in the consuming project, it will be an EmbeddedResource when you build the project:
在此输入图像描述

For me, contentFiles not working for ProjectReferenes. I need to use my own c++ dll with c# proxy. For universal nuget for packages.config and PackageReferences I've done next:

  1. c++ dll and MyCompany.MyDep.CppClient.targets was added to nuget packet project:

    • CppClient (solution dir)
    • CppClient (c# proxy project dir)
      • lib\\mycpp.dll (c++ dll)
      • MyCompany.MyDep.CppClient.targets
      • CppClient .csproj
      • ...
    • CppClient .sln.
  2. To CppClient.csproj was added next declaration:

    -- This is for packages.config projects Always true content\\$(TargetFramework) -- This is for ProjectReferenes projects - dll Always true build\\$(TargetFramework) -- This is for ProjectReferenes projects too - targets for copy dll Always true build\\$(TargetFramework)
  3. MyCompany.MyDep.CppClient.targets is:

    %(RecursiveDir)%(FileName)%(Extension) PreserveNewest
  4. From CppClient (solution dir) run command dotnet pack CppClient -c Release --output ./package /p:Version=1.0.0 /p:PackageID=MyCompany.MyDep.CppClient

  5. MyCompany.MyDep.CppClient.1.0.0.nupkg has next structure:

    • MyCompany.MyDep.CppClient.1.0.0
      • build\\arch
        • MyCompany.MyDep.CppClient.targets
        • mycpp.dll
      • content\\arch
        • mycppdll
      • lib\\arch
        • CppClient.dll
      • ...

MyCompany.MyDep.CppClient.1.0.0.nupkg can be installed to projects with both types of nuget packages management. For projects with packages.config works magic part of content directory in nuget pack, all it contents will be copied to target project folder, AFTER NUGET PACK IS INSTALLED TO PROJECT. Then it should be copied to final bin directory for being downloaded in runtime (you shuold do it by youself). For projects with ProjectReferenes works magic copy build\\arch\\mycpp.dll by build\\arch\\MyCompany.MyDep.CppClient.targets not right after you installed nuget pack, but WHEN TARGET PROJECT IS ALREADY BUILT. mycpp.dll not be copied to target project sources dir after nuget pack is installed. It will be include in referenced nuget of target project and be copied direct to output dir for binary after target project is built.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM