NuGet v4 中的 contentFiles 未被复制到输出目录

9

我在使用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元素等。
编辑:消费项目使用PackageReferences来获取NuGet packages,而不是packages.config。
3个回答

12
使用 PackageReferencecontentFilespackages.config 中的 content 有根本性的不同。对于 packages.config,您必须使用工具(Visual Studio)安装包,在安装时,NuGet 将把 content 复制到项目目录中并进行其他更改(例如告诉 Project System 修改 csproj)。对于 packages.config,还原的概念与安装是不同的,而所有还原只是在预期位置解压缩包,以便在编译时可用 lib/<tfm>/*.dll 程序集。

使用 PackageReference 可以手动编辑 csproj,而无需工具知道发生了这种情况。这意味着当 NuGet 进行还原时,它不知道这是否是为该项目恢复特定包的第一次,或者仅是在此计算机上第一次(实际上,NuGet 甚至不会检查计算机上项目的现有状态,因此当前它不知道包是否在当前计算机上先前已经在项目中恢复过)。虽然仍然可以使用工具(Visual Studio 或 dotnet add package),但这只是一种方便编辑 csproj 的方式。 这就是说,使用 PackageReference,安装与还原的概念不再存在。现在只有还原。

由于使用了PackageReference,安装的概念不再存在,这就引发了一个很大的问题:如果NuGet将文件复制到消费项目的目录中,如何处理内容文件? 如果NuGet在每次还原时都复制文件,则意味着如果项目的开发人员修改文件,则在下一次NuGet还原时它们会丢失更改。 如果NuGet不覆盖文件,则当项目改变包版本时,新包中的新内容将不会更新。
因此,contentFiles 的工作方式是,NuGet向构建系统通知文件,并将它们用作从全局包文件夹的链接。对于.NET Framework TFMs,在构建时或对于.NET Core TFMs,在发布时,将文件复制到输出目录。但是它们永远不会被复制到项目目录中。如果使用Visual Studio,它们应该出现在“解决方案资源管理器”中,但是如果单击文件以打开它,则以只读模式打开它,因为在全局包文件夹中进行项目特定更改是不好的,该文件夹由计算机上的所有项目使用。因此,在概念上类似于在每次构建时复制文件,并且为了防止使用项目的开发人员进行更改,它不会烦扰将文件复制到目录中。这还意味着要检查的内容更少。由于您正在使用的内容文件是构建时资产而不是运行时资产,因此我建议将您的规则集文件放在build/目录中,紧邻props文件。由于您的props文件未指定路径到规则集文件,我相信它告诉MSBuild查找props文件所在的目录,因此它将正常工作。最坏的情况是将其更改为$(MSBuildThisFileDirectory)StyleCop.ruleset。这是在假设您不介意使用项目无法修改规则集文件的情况下。如果您希望他们能够修改文件,则NuGet不是适当的交付机制,我建议您查看dotnet new item templates

2
是的,我昨天实际上自己解决了所有这些问题。 我使用了.nuspec中的<contentFiles><files include="**/*.*" buildAction="None" copyToOutput="true" flatten="true" /></contentFile><file src="content\**" target="contentFiles\any\any" />.. 然后在.props文件中使用了<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)..\content\StyleCop.ruleset</CodeAnalysisRuleSet>.. 无法编辑stylecop文件实际上是理想的,因为它将防止人们进行意外更改。谢谢! - jacob21
不错的详细解释 - Advait Baxi

3
我遇到了一个问题,当我进行了很多更改但没有任何作用时,最终通过使用PackageReferences解决了这个问题。对于packages.config项目,使用content/,而对于PackageReference项目,则使用contentFiles/。您可以在这里找到有关不可变内容的更多信息:ContentFilesExamplenuget-contentFiles-demystified。以下是解决方法的步骤:
1. 通过packages.config引用NuGet包的现有项目。 2. 安装带有内容文件的NuGet包。 3. 构建项目。 4. 输出目录中没有内容文件。 5. 将packages.config转换为PackageReferences。 6. 构建项目。 7. 内容文件已复制到输出目录。
IDE为Visual Studio 2017。该项目是应用程序项目,也就是说它是旧的csproj格式。更新后的答案如下:向PackageReference添加了GeneratePathProperty属性。
<PackageReference Include="EO.Pdf" GeneratePathProperty="true">
    <Version>19.0.83</Version>
</PackageReference>

请检查您的\obj\.csproj.nuget.g.props文件以验证变量是否已生成。

这些变量以Pkg为前缀。看起来它们会自动生成所有包含tools文件夹的NuGet包的变量。


是的,我们的项目已经在.csproj文件中使用PackageReferences了。我们不使用packages.config。我会编辑问题来添加这一点。 - jacob21
@jacob21 我已更新答案。另外,请参考此处 - Vignesh Kumar A
4
很遗憾,这也没有产生任何不同。 - jacob21

1

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