将 'content' 重新添加到使用 "Package References" 的项目的工具或方法

Tooling or method to re-add 'content' to projects utilizing "Package References"

  1. 一个项目(原始VS格式)被转换为使用包引用。太好了。

  2. 项目引用“不支持内容”。有问题的选择,虽然这里没有争论。

  3. 一些使用过的包包含“内容”,不能或不会更新为使用“内容文件”。嗯..

可以使用什么半自动化工具/方法从“不支持 contentFiles”的 NuGet 依赖项复制“内容”+ 直接申请包就可以了


+自然地,可以手动打开每个单独的 NuGet 文件并复制内容。这个问题不是关于“为什么”进行转换 and/or 任何优点或权衡 and/or 如何“应该”编写程序包。问题是关于能够将“内容”恢复到项目源代码树中的自动化或半自动化方法。

Tooling or method to re-add 'content' to projects utilizing “Package References”

恐怕没有这样的工具可以将内容文件夹中的文件制作成 PackageReference nuget 管理格式的项目。

作为包的用户,目前没有工具可以将content文件夹的文件复制到带有PackageReference.

其实如果有这样的工具,也违反了nuget的机制。 所有这些都依赖于 nuget 包的作者而不是用户,除非包是由我们编写的

建议

因此您必须手动解压 nuget 包并将文件复制到您的项目中。

它似乎有点复杂,如果您仍然想以一种简单的方式获得您想要的东西,我建议您可以在我们的 User Voice Forum.

上推荐一个功能

然后,你可以在这里分享link,任何对它感兴趣的人都会投票,这样它会得到更多 Microsoft 的关注。所有这些都有助于尽快得到你想要的。

可以将基于“内容”的 NuGet 包与已转换为使用包引用的原始 Visual Studio/MSBuild 项目一起使用。

所提供的解决方案也可以针对 SDK-style 项目进行修改。这个壮举是通过利用 PackageReference+GeneratePathProperty 属性来完成的。使用生成的 Pkg* 路径属性可确保引用包的有效路径。 (注意:如果包名包含 .,请在 Pkg* 属性 名称中将其替换为 _。)

首先,将GeneratePathProperty添加到所有要复制内容的包或link。

<PackageReference Include="bootstrap" GeneratePathProperty="true">
  <Version>Don't ask..</Version>
</PackageReference>
<PackageReference Include="AngularJS.Core" GeneratePathProperty="true">
  <Version>..it's not great</Version>
</PackageReference>

“获取内容”

根据需要,此处介绍了两种不同的方法。虽然这些方法可以一起使用,但两种方法都不应应用于基于“内容文件”的 NuGet 包。

方法 #1:将内容复制到项目源代码

通过这种方法,可以将文件添加到源代码管理中。因此,项目中的以下几行在更新包时可以 un-commented(和 re-commented)以确保最新的 NuGet 包内容。

它使用 Copy 任务来复制内容。

<ItemGroup>
  <NugetContentToRestore Include="
                         $(Pkgbootstrap)\Content\**\*.*;
                         $(PkgAngularJS_Core)\Content\**\*.*;
                         " />
</ItemGroup>
<Target Name="BeforeBuild">
  <Copy SourceFiles="@(NugetContentToRestore)"
        DestinationFiles="@(NugetContentToRestore->'$(ProjectDir)\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>

如果正常开发时不注释掉ItemGroup,项目会被包含在项目的解决方案资源管理器根目录中,有点难看。也无法检测到“内容”何时被删除。

方法 #2:内容 Link

如果要将 none 的内容复制 and/or 与项目一起检入源代码管理,也可以 link 编辑。这种方法的好处是始终 link 浏览最新内容并且不会污染解决方案资源管理器。

项目中明确包含的本地文件将优先于 linked 资源。

对于普通项目(和 bin-deployed 文件)

对于普通项目,<CopyToOutputDirectory> 就足够了,linked 文件将进入 'bin' 输出。但是,这不适用于仅理解项目树中实际存在的文件的 Web 项目。

<ItemGroup>
  <Content Include="$(Pkgbootstrap)\Content\**\*.*">
    <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </Content>
  <Content Include="$(PkgAngularJS_Core)\Content\**\*.*">
    <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </Content>
</ItemGroup>

对于 Web 项目(需要本地文件

对于 Web 项目,必须将这些 link 复制到本地文件:<CopyToOutputDirectory> 是不够的或必需的。 应该进入 bin 输出内容的包应该使用上面的方法。

<ItemGroup>
  <Content Include="$(Pkgbootstrap)\Content\**\*.*">
    <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
  </Content>
  <Content Include="$(PkgAngularJS_Core)\Content\**\*.*">
    <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
  </Content>
</ItemGroup>

然后添加一个目标来复制 linked 文件,以便 Web 项目工具选择它们。参见 Copying linked content files at each build using MSBuild。它可能是相关的,因此跳过某些 links 并添加源代码管理忽略条目。

<Target Name="CopyLinkedContentFiles" BeforeTargets="Build">
  <Copy SourceFiles="%(Content.Identity)"
        DestinationFiles="%(Content.Link)"
        SkipUnchangedFiles='true'
        OverwriteReadOnlyFiles='true'
        Condition="'%(Content.Link)' != ''" />
</Target>

+这适用于 up-to-date Visual Studio 2019 环境。它可能不适用于某些较旧的 MSBuild/NuGet 配置,因为需要 Pkg* 属性 代。