NuGet v4 contentFiles 没有被复制到输出 [英] NuGet v4 contentFiles not getting copied to output

查看:76
本文介绍了NuGet v4 contentFiles 没有被复制到输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 NuGet v4 CLI 将文件复制到输出时遇到问题.

I'm having trouble with NuGet copying files to output, using NuGet v4 CLI.

我的目录结构如下:

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

这是我的 CodeAnalyzer.props 文件:

Here's my CodeAnalyzer.props file:

<?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 文件:

And CodeAnalyzer.nuspec file:

<?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 上,我正在使用:

On CLI I am packing using:

.\nuget.exe 包 .\CodeAnalyzer.nuspec

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

In the resulting .nupkg, there is a contentFiles directory with the StyleCop.ruleset file in, so that works.

如果我随后将包安装到项目中,它会很好地获取 StyleCop.Analyzers 依赖项,并查找 StyleCop.ruleset 文件,因此 .props 文件很好.

If I then install the package in a project, it picks up on the StyleCop.Analyzers dependency fine, and it looks for the StyleCop.ruleset file, so the .props file is fine.

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

But the StyleCop.ruleset file isn't placed anywhere.

感觉我已经尝试了很多将 buildActions 更改为 None/Content,将 copyToOutput 更改为 true/false,contentFiles.file 元素和 file.file 元素的不同路径.

Feel like I've tried a lot of changing buildActions to None/Content, copyToOutput to true/false, different paths for the contentFiles.file element and the file.file element.

消费项目使用的是 NuGet 包的 PackageReferences,而不是 packages.config.

the consuming project is using PackageReferences for NuGet packages, not packages.config.

推荐答案

contentFiles with PackageReferencecontent with 的工作方式根本不同包.config.使用 packages.config,您必须使用工具 (Visual Studio) 来安装包,并且在安装时,NuGet 会将 content 复制到项目目录以及它的任何其他更改需要(比如告诉项目系统修改 csproj).使用 packages.config 还原在概念上与安装不同,还原所做的所有操作都是将包解压缩到预期位置,以便 lib//*.dll程序集在编译时可用.

contentFiles with PackageReference works fundamentally differently to content with packages.config. With packages.config, you must use tooling (Visual Studio) to install packages, and at install-time, NuGet will copy content to the project directory and whatever other changes it needs to (like telling the Project System to modify the csproj). With packages.config restore is conceptually different to install, and all restore does is unzip the package in the expected location so that the lib/<tfm>/*.dll assemblies are available at compile-time.

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

With PackageReference it's possible to hand edit the csproj without tooling having any knowledge this happened. This means when NuGet does a restore, it has no idea if this is the first time a particular package was restored for the project, or just the first time on this computer (in fact, NuGet doesn't even check the existing state of the project on the machine, so currently it has no idea if the package has been previously restored in the project on the current computer). Although you can still use tooling (Visual Studio, or dotnet add package), this is nothing more than a convenient way to edit the csproj. This is a long way to say that the concept of install vs restore no longer exists with PackageReference. There is now only restore.

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

Since the concept of install no longer exists with PackageReference, there's a big question about how to do content files, if NuGet were to copy files to the consuming project's directory. If NuGet copies the file every restore, it means if the developers of the project modify the file, they lose their changes on the next NuGet restore. If NuGet doesn't overwrite files, then when the project changes the package version, the new content from the new package will not be updated.

因此,contentFiles 的工作方式是 NuGet 将这些文件告知构建系统,并将它们用作全局包文件夹中的链接.在 .NET Framework TFM 的构建时或 .NET Core TFM 的发布时,文件将复制到输出目录.但是它们绝不会被复制到项目目录中.如果使用 Visual Studio,它们应该出现在解决方案资源管理器中,但是如果您单击一个文件来打开它,它将以只读模式打开,因为对使用的全局包文件夹进行项目特定的更改是不好的通过计算机上的所有项目.因此,从概念上讲,它类似于在每次构建时复制文件,并且为了阻止使用项目的开发人员进行更改,它不会将文件复制到目录中.这也意味着无需检查源代码管理.

So, the way that contentFiles works is that NuGet tells the build system about the files, and they're used as links from the global packages folder. At build time for .NET Framework TFMs, or at publish time for .NET Core TFMs, the files are copied to the output directory. But at no time are they ever copied to the project directory. If using Visual Studio, they should appear in Solution Explorer, but if you click a file to open it, it opens in read-only mode, since it would be bad to make project-specific changes to the global packages folder, which is used by all projects on the computer. So, conceptually it's similar to copying the file on every build, and in order to discourage developers of the consuming project from making changes, it doesn't bother copying the files to the directory. It also means there's less to check into source control.

由于您使用的内容文件是构建时资产,而不是运行时资产,我建议 contentFiles 不是放置规则集文件的正确位置.我只是将它放在props 文件旁边的build/ 目录中.由于您的 props 文件没有指定规则集文件的路径,我相信它告诉 MSBuild 在 props 文件的目录中查找,所以它会正常工作.最坏的情况是将其更改为 $(MSBuildThisFileDirectory)StyleCop.ruleset.这是假设您对无法修改规则集文件的消费项目没问题.如果您确实希望他们能够修改文件,那么 NuGet 不是合适的交付机制,我建议您查看 dotnet 新项目模板.

Since the content file you're using is a build-time asset, not a runtime asset, I suggest that contentFiles is not the right place to put your ruleset file. I'd just put it in the build/ directory next to your props file. Since your props file doesn't specify a path to your ruleset file, I believe it tells MSBuild to look in the props file's directory, so it'll just work. Worst case you change it to $(MSBuildThisFileDirectory)StyleCop.ruleset. This is under the assumption you're fine with the consuming projects not being able to modify the ruleset file. If you do wish them to be able to modify the file, then NuGet is not an appropriate delivery mechanism, and I suggest you look at dotnet new item templates instead.

这篇关于NuGet v4 contentFiles 没有被复制到输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆