问题描述
可以使用哪种半自动化的工具/方法从“不支持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上推荐一个功能。
然后,您可以在此处共享该链接,对此感兴趣的任何人都将对其进行投票,从而使它得到 Microsoft 的更多关注。所有这些都将帮助您尽快获得想要的东西。