【问题标题】:Tooling or method to re-add 'content' to projects utilizing "Package References"使用“包引用”为项目重新添加“内容”的工具或方法
【发布时间】:2020-09-02 16:54:11
【问题描述】:
  1. 一个项目(原始VS格式)被转换为使用包引用。太好了。

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

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

什么半自动化工具/方法可用于从“不支持 contentFiles”的 NuGet 依赖项中复制“内容”+ 仅适用于直接包没问题。


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

【问题讨论】:

    标签: visual-studio nuget packagereference


    【解决方案1】:

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

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

    首先,将GeneratePathProperty 添加到所有包含要复制或链接的内容的包中。

    <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:将内容复制到项目源

    通过这种方法,可以将文件添加到源代码管理中。因此,在更新包以确保最新的 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,那么item会被包含在项目的解决方案资源管理器根目录下,有点丑。也无法检测“内容”何时被删除。

    方法 #2:内容中的链接

    如果没有任何内容要与项目一起复制和/或签入源代码管理,也可以将其链接。这种方法的好处是始终链接最新的内容,并且不会污染解决方案资源管理器.

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

    对于普通项目(和 bin 部署的文件)

    对于普通项目,&lt;CopyToOutputDirectory&gt; 就足够了,链接的文件将进入“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 项目,必须将这些链接复制到本地文件:&lt;CopyToOutputDirectory&gt; 不够或不需要。内容应该进入 bin 输出的包应该使用上述方法。

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

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

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

    +这适用于最新的 Visual Studio 2019 环境。它可能不适用于某些较旧的 MSBuild/NuGet 配置,因为需要生成 Pkg* 属性。

    【讨论】:

    • 既然你有一个解决方法,我建议你可以标记你自己的答案。无论如何,感谢您分享解决方案并让我们学习它。
    【解决方案2】:

    利用“包”为项目重新添加“内容”的工具或方法 参考文献”

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

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

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

    建议

    所以你必须手动解压nuget包并将文件复制到你的项目中。

    而且它似乎有点复杂,如果你仍然想通过一种简单的方式来获得你想要的东西,我建议你可以在我们的User Voice Forum 上推荐一个功能。

    然后,您可以在此处分享链接,任何对此感兴趣的人都会对其进行投票,以便获得更多微软的关注。所有这些都将有助于尽快得到您想要的。

    【讨论】:

    • 这个问题不是在征求PackageReferences的“精神”,也不是询问带有“内容文件”的包。它是关于如何恢复“内容”的请求,例如来自尚未更新的旧 NuGet 包。 如问题所述,这可以手动完成。似乎存在以自动化(并且在很大程度上可重复)的方式执行此手动过程的自动化方法。
    • 为了明确起见,我添加了#3。这个问题不是关于让“内容文件”表现得像“内容”。这是关于恢复旧包提供的“内容”。
    • 我想我花了一天时间编写一些 PowerShell 以自动执行手动步骤。看起来这真的不是一个“新颖”的问题。我花了一段时间在互联网上搜索,到处都是“正当理由”,没有可行的解决方案。
    • 公开任何关于 NuGet 团队创建的此类工具的此类请求也是毫无意义的。至少自 2017 年以来,这些请求已作为“设计”关闭,而未能考虑“内容”的现有使用,有时是必需的/有用的使用。如果“选择”确实在 NuGet 范围之外,那么支持这种选择似乎是合理的,即使不是首选或在默认执行路径中也是如此。而且..不。
    • “MSBuild.NugetContentRestore”包需要 packages.config,因为前提似乎足以完成任务。无论如何,这是一个几乎足够的工具示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-26
    • 2013-02-06
    • 2017-05-23
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多