NuGet v4 contentFiles未复制到输出

时间:2019-11-08 13:14:40

标签: nuget nuget-package nuget-package-restore nuget-spec

使用NuGet v4 CLI,NuGet在将文件复制到输出时遇到麻烦。

我的目录结构如下:

repo
repo\CodeAnalyzer.nuspec
repo\CodeAnalyzer.props
repo\contentFiles\any\any\StyleCop.ruleset

这是我的CodeAnalyzer.props文件:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <PackageName>CodeAnalyzer</PackageName>
    <PackageVersion>0.1.0</PackageVersion>
  </PropertyGroup>
  <PropertyGroup>
      <CodeAnalysisRuleSet>StyleCop.ruleset</CodeAnalysisRuleSet>
  </PropertyGroup>
</Project>

和CodeAnalyzer.nuspec文件:

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata>
    <id>CodeAnalyzer</id>
    <description>Provides standard code analyzer tooling and customisation.</description>
    <authors>Me</authors>
    <version>0.1.0</version>
    <dependencies>
      <dependency id="StyleCop.Analyzers" version="1.1.118" />
    </dependencies>
    <contentFiles>
      <files include="any/any/*" buildAction="Content" copyToOutput="true" flatten="false" />
    </contentFiles>
  </metadata>
  <files>
    <file src="contentFiles\any\any\StyleCop.ruleset" target="contentFiles" />
    <file src="CodeAnalyzer.props" target="build" />
  </files>
</package>

在CLI上,我使用以下命令进行打包:

.\nuget.exe pack .\CodeAnalyzer.nuspec

在生成的.nupkg中,存在一个ContentFiles目录,其中包含StyleCop.ruleset文件,因此可以正常工作。

如果我随后将软件包安装在项目中,则可以使用StyleCop.Analyzers依赖项很好,并且可以查找StyleCop.ruleset文件,因此.props文件可以。

但是StyleCop.ruleset文件没有放置在任何地方。

感觉就像我尝试了很多将buildActions更改为None / Content,将copyToOutput更改为true / false一样,将contentFiles.file元素和file.file元素设置为不同的路径。

编辑:正在使用的项目正在对NuGet软件包而不是packages.config使用PackageReferences。

3 个答案:

答案 0 :(得分:1)

带有contentFiles

PackageReference与带有content的{​​{1}}的工作原理根本不同。使用packages.config,您必须使用工具(Visual Studio)来安装软件包,并且在安装时,NuGet会将packages.config复制到项目目录以及其他需要进行的更改(例如告诉项目系统)修改csproj)。使用content还原在安装上在概念上有所不同,所有还原所做的就是将软件包解压缩到预期的位置,以便packages.config程序集在编译时可用。

使用lib/<tfm>/*.dll可以手动编辑csproj,而无需任何工具就能知道发生了什么。这意味着当NuGet还原时,它不知道这是第一次为项目还原特定的软件包,还是这是第一次在该计算机上还原(实际上,NuGet甚至不检查其现有状态)。机器上的项目,因此目前尚不知道该软件包之前是否已在当前计算机上的项目中还原。尽管您仍然可以使用工具(Visual Studio或PackageReference),但这仅是编辑csproj的便捷方法。很长一段话说,dotnet add package不再包含安装与还原的概念。现在只有还原。

由于PackageReference中不再存在安装的概念,因此如果NuGet将文件复制到使用项目的目录中,那么如何处理内容文件存在很大的问题。如果NuGet在每次还原时都复制文件,则意味着如果项目的开发人员修改了文件,则他们在下一次NuGet还原时将丢失所做的更改。如果NuGet不会覆盖文件,则当项目更改软件包版本时,新软件包中的新内容将不会更新。

因此,PackageReference的工作方式是NuGet告诉构建系统有关文件的信息,它们被用作全局程序包文件夹中的链接。在.NET Framework TFM的构建时,或在.NET Core TFM的发布时,文件被复制到输出目录。但是它们绝不会复制到项目目录中。如果使用Visual Studio,它们应该出现在解决方案资源管理器中,但是如果您单击一个文件将其打开,则它将以只读模式打开,因为对全局软件包文件夹进行特定于项目的更改会很麻烦。通过计算机上的所有项目。因此,从概念上讲,这类似于在每个内部版本上复制文件,并且为了阻止使用中项目的开发人员进行更改,它不会打扰将文件复制到目录中。这也意味着要检查源代码控制的内容更少。

由于您使用的内容文件是构建时资产,而不是运行时资产,因此我建议contentFiles不是放置规则集文件的正确位置。我只是将其放在您的contentFiles文件旁边的build/目录中。由于您的props文件未指定规则集文件的路径,因此我相信它告诉MSBuild在props文件的目录中进行查找,因此它可以正常工作。最坏的情况是将其更改为props。这是在您认为使用项目无法修改规则集文件的情况下您认为很好。如果您确实希望他们能够修改文件,那么NuGet不是合适的传送机制,建议您改用dotnet new item templates

答案 1 :(得分:0)

当我进行了很多更改而没有任何效果时,我遇到了这个问题。最后使用PackageReferences

解决

packages.config项目使用content/ PackageReference项目使用contentFiles/

您可以在此处找到有关不变内容的更多信息:

ContentFilesExample

nuget-contentFiles-demystified

  1. 通过packages.config带有nuget引用的现有项目
  2. 已安装带有内容文件的NuGet软件包
  3. 构建项目
  4.   

    输出目录中没有内容文件

  5. packages.configPackageReferences的转换
  6. 构建项目
  7.   

    内容文件已复制到输出目录

IDE是Visual Studio2017。该项目是一个应用程序项目,意味着它采用旧的csproj格式。

更新后的答案

GeneratePathProperty属性已添加到PackageReference

<PackageReference Include="EO.Pdf" GeneratePathProperty="true">
    <Version>19.0.83</Version>
</PackageReference>

检查您的\ obj \ .csproj.nuget.g.props以验证是否生成了变量

变量以Pkg开头。听起来好像是使用工具文件夹为所有nuget软件包自动生成的。

答案 2 :(得分:0)

这是解决这个问题的另一个答案:

https://stackoverflow.com/a/68243917/56621

TL;DR - 将文件打包到包中时,请确保遵循目标框架/语言的“any/any”命名约定,否则将无法工作

相关问题