使用“包装参考”将项目的“内容”重新添加到项目的工具或方法 对于普通项目以及Bin部署的文件对于Web项目需要本地文件

问题描述

  1. 项目(原始VS格式)被转换为 use 包引用。很好。

  2. 项目引用“不支持内容”。选择值得怀疑,尽管这里没有争论。

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

可以使用哪种半自动化的工具/方法从“不支持contentFiles” + 的NuGet依赖项中复制“内容”?仅适用于直接包装很好。


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

解决方法

可以将基于“内容”的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,则这些项目将包含在项目的解决方案资源管理器根目录中,这有点丑陋。也无法检测到何时删除了“内容”。

方法2:内容链接

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

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

对于普通项目(以及Bin部署的文件)

对于普通项目,<CopyToOutputDirectory>就足够了,链接的文件将进入“ 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项目,必须将这些链接复制到本地文件:<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>

然后添加一个目标来复制链接的文件,以便Web Project工具将其拾取。参见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*属性。

,

使用“软件包”将“内容”重新添加到项目中的工具或方法 参考”

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

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

而且实际上,如果有这样的工具,它也违反了nuget的机制。 所有这些依赖于nuget软件包的作者而不是用户,除非该软件包是由我们创作的

建议

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

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

enter image description here

然后,您可以在此处共享该链接,对此感兴趣的任何人都将对其进行投票,从而使它得到 Microsoft 的更多关注。所有这些都将帮助您尽快获得想要的东西。