Nuget包的contentFiles未复制到.NET Core项目中

13

我正在尝试将Nuget包中的内容文件提取到引用我的包的项目中。

根据Justin Emgarten的评论

Packages.config项目使用content文件夹

Project.json/PackageReference/NETCore SDK项目使用contentFiles文件夹

好的,很棒,我创建了一个.NET Core 2.1控制台应用程序项目,并按照NuGet ContentFiles Demystified博客文章的说明进行操作,该文章是在2016年写的,当时使用的是project.json,但现在仍然适用。

我在c:\dev\ContentFilesExample\contentFiles\any\any\images\dnf.png处创建了一个图像,然后创建了一个c:\dev\ContentFilesExample\ContentFilesExample.nuspec文件,并复制粘贴了内容:

<?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>

然后我使用命令nuget pack ContentFilesExample.nuspec生成了Nuget包,然后使用Nuget包浏览器打开它。

enter image description here

太好了,我的图片如预期一样出现了。

现在是最后一个无法工作的步骤。我在我的.NET Core 2.1项目中安装了这个Nuget包,但是图片丢失了。在我的项目根目录、obj文件夹或bin文件夹中都找不到图片的痕迹。

我尝试像某些评论中所述的那样关闭并重新打开Visual Studio,但这并没有解决问题。

我还尝试将我的.NET Core项目风格更改为PackageReference,但同样也没有解决问题。

<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>

那么我做错了什么?Nuget包中的内容文件是否真正被.NET Core支持?

谢谢


可能是https://dev59.com/iKrka4cB1Zd3GeqPXAOR#70713807 的重复问题。 - Roeland Van Heddegem
3个回答

26

我在经过数小时的谷歌搜索后,最终找到了这个问题,因此我决定写另一个答案来澄清事情(因为微软文档很烂)。

  1. .nuspec 文件中的 <files> 元素是用于打包程序的。它告诉NuGet要打包哪些文件(如果您的nuspec中没有<files>元素,则NuGet将使用目录命名约定)。
  2. <contentFiles> 元素是给消费者用的 - 它告诉他们如何以及何时提取文件。
  3. 如果您想在安装后在项目中看到文件 - 您必须使用一个target 将其打包contentFiles/any/any,其中“any/any”部分告诉NuGet它适用于任何语言和任何框架。
  4. (可选)如果您还希望该文件与使用packages.config的旧NuGet模式一起使用 - 您需要再次打包它,第二次将其打包到“内容”文件夹中,以便旧版的消费者仍然可以使用它。

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>

附注:我的博客文章这里有更多详细信息。


非常感谢,其他地方没有解释这个旧格式和新格式的区别。 - CBBSpike
但是在旧格式上,似乎没有遵循contentFiles。我要求复制到输出,但标志从未设置。新格式运行良好。 - CBBSpike
1
有没有一种方法可以不使用nuspec文件,而是直接将其纯粹地放入csproj文件中? - syter
Alex的答案帮了我很多,但是我需要在我的元数据中加入 <files include="**/*.exe.config" buildAction="Content" copyToOutput="true" flatten="true" /> - Jeremy

5
nupkg应该有contentFiles/目录:
nupkg 安装到netcore项目中:
enter image description here 当您构建项目时,它不会成为使用项目中的散文件,而是一个EmbeddedResource:
enter image description here

哇,太棒了,伙计!你今天已经帮我解决了第二个Nuget问题。为你干杯!我想下一个Nuget包我会再次使用contentFilesContent。很高兴我终于让这个黑魔法起作用了(我的问题是我实际上忘记创建contentFiles的Windows文件夹,因此该目录在包中丢失)。 - Jérôme MEVEL

0

对我来说,contentFiles 在 ProjectReferenes 中不起作用。 我需要使用自己的 c++ dll 与 c# 代理一起使用。 对于 packages.config 和 PackageReferences 的通用 nuget,我已经完成了以下操作:

1. 将C++ DLL和MyCompany.MyDep.CppClient.targets添加到NuGet包项目中:
  • CppClient(解决方案目录)
  • CppClient(C#代理项目目录)
    • lib\mycpp.dll(C++ DLL)
    • MyCompany.MyDep.CppClient.targets
    • CppClient.csproj
    • ...
  • CppClient.sln。
2. 向CppClient.csproj添加以下声明:
-- 这是用于packages.config项目的 Always true content\$(TargetFramework) -- 这是用于ProjectReferenes项目的 - DLL Always true build\$(TargetFramework) -- 这也适用于ProjectReferenes项目 - 用于复制DLL的targets Always true build\$(TargetFramework) 3. MyCompany.MyDep.CppClient.targets内容如下:
%(RecursiveDir)%(FileName)%(Extension) PreserveNewest
4. 从CppClient(解决方案目录)运行命令 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具有以下结构:
  • 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 可安装到使用两种类型 NuGet 包管理的项目中。 对于使用 packages.config 的项目,在 NuGet 打包时,如果 content 目录下包含的所有内容都会被复制到目标项目文件夹中,AFTER NUGET PACK IS INSTALLED TO PROJECT,然后应该将其复制到最终的 bin 目录中以便在运行时下载(需要自己执行)。 对于使用 ProjectReferenes 的项目,在安装 NuGet 包之后,并不会立即复制 build\arch\mycpp.dll,而是需要在已经构建目标项目时,通过使用 build\arch\MyCompany.MyDep.CppClient.targets 来复制。 mycpp.dll 不会在安装 nuget 包后直接复制到目标项目源目录中,而是包含在目标项目的引用 NuGet 中,并在构建目标项目后直接复制到输出目录中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接