如何最快速地将旧的 NuGet 包 (2.x, packages.config) 升级成新的 NuGet 包 (4.x, PackageReference)
最近我将项目格式进行了升级,从旧的 csproj 升级成了新的 csproj;NuGet 包管理的方式也从 packages.config 升级成了 PackageReference。然而迁移完才发现,这个项目竟然还依赖了大量的从 NuGet 2.x 时代发布的 NuGet 包,这些包并不能在 PackageReference 下好好工作。
于是,我准备将所有这些包都进行升级。本文将介绍最简单的升级步骤。
回顾遇到的问题
如果你之前迁移过 csproj 文件,可能会遇到问题。关于迁移 csproj 文件,可以阅读:将 WPF、UWP 以及其他各种类型的旧样式的 csproj 文件迁移成新样式的 csproj 文件 - 吕毅。
如果你并没有迁移过 csproj 文件,只是升级了 NuGet 的包管理方式,也可能会遇到问题。关于自动迁移 NuGet 包管理方式,可以阅读:自动将 NuGet 包的引用方式从 packages.config 升级为 PackageReference - 吕毅。
在自动迁移那篇文章中,我提到了一些兼容性问题,最大的莫过于 Install.ps1 脚本不再执行:
使用 PackageReference 后,在安装和写在的过程中 install.ps1 脚本将不再执行。如果有一些行为依赖于此脚本,那么这个 NuGet 包的行为可能不正常。
但是,不用担心!install.ps1 的存在是因为 packages.config 不支持 PackageReference 中的一些新特性(例如 NuGet 包中新的目录结构,例如包中自带的 msbuild targets)。所以,如果 NuGet 包在发布时满足目录要求,那么即便 install.ps1 不用执行也能保证包的行为正常。
虽然我提到不用担心,但其实旧的一些包里并没有准备 build 文件夹,也没有准备 props 或者 targets 文件。所以一小部分特别依赖于 install.ps1 的 NuGet 包是没有办法在新格式中生效的。
最简升级步骤
知道了问题所在,那么我们的根本便是将 Install.ps1 升级成新的 props 或者 targets。
如果你不清楚 props 或者 targets 是什么意思,或者不知道怎么写它们,可以阅读我的另一篇文章理解 C# 项目 csproj 文件格式的本质和编译流程 - 吕毅。
第一步:将 install.ps1 翻译成 targets
最简单的方法,直接去安装好 NuGet 的项目的 csproj 文件中去看究竟生成了那些代码。一般来说,这些 install.ps1 中多是生成 Target 节点。
而我们要做的,就是新建一个 build 文件夹,在其中新建 PackageId.targets 文件,以便将生成的 Target 节点中的内容复制过去。前面那一句的 PackageId 指的是这个 NuGet 包的包 Id。比如,在我的例子中,是 Walterlv.NuGetDemo.targets。
比如,生成的 Target 节点是这样的:
<!-- 项目 csproj 文件 -->
<Target Name="WalterlvNuGetDemo" BeforeTargets="AfterCompile">
<ItemGroup>
<BinCopyItems Include="..\..\packages\Walterlv.NuGetDemo.1.2.3.0\tools\bin\*.*" />
<x64CopyItems Include="..\..\packages\Walterlv.NuGetDemo.1.2.3.0\tools\bin_x64\*.*" />
<x86CopyItems Include="..\..\packages\Walterlv.NuGetDemo.1.2.3.0\tools\bin_x86\*.*" />
</ItemGroup>
<Copy SourceFiles="@(BinCopyItems)" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="True" />
<Copy SourceFiles="@(x86CopyItems)" DestinationFolder="$(OutputPath)x86" SkipUnchangedFiles="True" />
<Copy SourceFiles="@(x64CopyItems)" DestinationFolder="$(OutputPath)x64" SkipUnchangedFiles="True" />
</Target>
那么,直接将这些文件复制到 PackageId.targets 文件中:
<!-- Walterlv.NuGetDemo.targets 文件 -->
<Project>
<Target Name="WalterlvNuGetDemo" BeforeTargets="AfterCompile">
<ItemGroup>
<BinCopyItems Include="..\..\packages\Walterlv.NuGetDemo.1.2.3.0\tools\bin\*.*" />
<x64CopyItems Include="..\..\packages\Walterlv.NuGetDemo.1.2.3.0\tools\bin_x64\*.*" />
<x86CopyItems Include="..\..\packages\Walterlv.NuGetDemo.1.2.3.0\tools\bin_x86\*.*" />
</ItemGroup>
<Copy SourceFiles="@(BinCopyItems)" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="True" />
<Copy SourceFiles="@(x86CopyItems)" DestinationFolder="$(OutputPath)x86" SkipUnchangedFiles="True" />
<Copy SourceFiles="@(x64CopyItems)" DestinationFolder="$(OutputPath)x64" SkipUnchangedFiles="True" />
</Target>
</Project>
然后,修改其中的路径,将相对于安装项目路径的地方更换成相对于此 targets 文件的路径:
<!-- Walterlv.NuGetDemo.targets 文件 -->
<Project>
<Target Name="WalterlvNuGetDemo" BeforeTargets="AfterCompile">
<ItemGroup>
<BinCopyItems Include="$(MSBuildThisFileDirectory)..\tools\bin\*.*" />
<x64CopyItems Include="$(MSBuildThisFileDirectory)..\tools\bin_x64\*.*" />
<x86CopyItems Include="$(MSBuildThisFileDirectory)..\tools\bin_x86\*.*" />
</ItemGroup>
<Copy SourceFiles="@(BinCopyItems)" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="True" />
<Copy SourceFiles="@(x86CopyItems)" DestinationFolder="$(OutputPath)x86" SkipUnchangedFiles="True" />
<Copy SourceFiles="@(x64CopyItems)" DestinationFolder="$(OutputPath)x64" SkipUnchangedFiles="True" />
</Target>
</Project>
第二步:修改 nuspec 文件,加入 targets
接着,去 nuspec 文件中,删除 Install.ps1 和 Uninstall.ps1,然后新增我们刚刚写的 targets 文件。
<files>
<!-- 省略其他一些文件 -->
<file src="tools\bin\DemoNativeLib.dll" target="tools\bin"/>
<!-- 删除 <file src="tools\Install.ps1" target="tools"/> -->
<!-- 删除 <file src="tools\Uninstall.ps1" target="tools"/> -->
<!-- 省略其他一些文件 -->
<file src="build\Walterlv.NuGetDemo.targets" target="build"/>
</files>
重新打包和测试 NuGet 包
以上改完了之后,基本上就迁移完了。
这样的改动是最小的,既能够保证旧的 packages.config 能够顺利迁移,也能保证新的 PackageReference 行为保持不变。
如何最快速地将旧的 NuGet 包 (2.x, packages.config) 升级成新的 NuGet 包 (4.x, PackageReference)的更多相关文章
- 自动将 NuGet 包的引用方式从 packages.config 升级为 PackageReference
在前段时间我写了一篇迁移 csproj 格式的博客 将 WPF.UWP 以及其他各种类型的旧样式的 csproj 文件迁移成新样式的 csproj 文件,不过全过程是手工进行的,而且到最后处理 XAM ...
- 在VS中自动生成NuGet包以及搭建自己的或单位内部的NuGet服务器
关于NuGet的介绍已经很多,可以参考下面的: NuGet学习笔记(1)--初识NuGet及快速安装使用 http://kb.cnblogs.com/page/143190/ NuGet学习笔记(2) ...
- 将 WPF、UWP 以及其他各种类型的旧样式的 csproj 文件迁移成新样式的 csproj 文件
写过 .NET Standard 类库或者 .NET Core 程序的你一定非常喜欢微软为他们新开发的项目文件(对于 C#,则是 csproj 文件).这种文件非常简洁,组织一个庞大的项目也只需要聊聊 ...
- 项目 XXX 的 NuGet 程序包还原失败:找不到“xxx”版本的程序包“xxx”
项目 XXX 的 NuGet 程序包还原失败:找不到“xxx”版本的程序包“xxx” 编译新下载的代码出错 修改包管理器的源为 http://www.nuget.org/api/v2/ .重试后成功 ...
- Error This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. T
错误提示: Severity Code Description Project File Line Suppression StateError This project references NuG ...
- Vs 中关于项目中的某 NuGet 程序包还原失败:找不到“xxx”版本的程序包“xxx”
问题: 首先出现这个bug的是在我的vs2017社区版的ide上,这两天使用了出现了一个非常神奇的问题,就是我程序中的nuget包总提示找不到源文件,并且我点击Nuget还原的话还一直提示着一 ...
- NuGet Packages are missing,This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.
错误内容 This project references NuGet package(s) that are missing on this computer. Use NuGet Package R ...
- 解决“程序包管理器控制台”输入命令找不到Nuget包问题
问题: 问题原因: Nuget源的地址上不去 解决办法: 1.将Nuget源更新为可以国内使用的官方Nuget源. 1)打开VS2013:工具-->Nuget程序包管理器-->程序包管理器 ...
- 手动更新了packages.config Nuget配置文件,自动引用dll
通过Google查询到:http://stackoverflow.com/questions/6876732/how-do-i-get-nuget-to-install-update-all-the- ...
随机推荐
- 综合一句话Shell破解
之前我在论坛发过了一句话的破解工具. 所以决定还是在基础上在改改,符合某些人的利用. 上一版只支持HTTPS/ASPX,这次改进后,也算是最后一版. 支持:PHP/HTTP/HTTPSASPX/HTT ...
- 异步提交表单插件jquery.form.min.js的使用实例
因为项目中需要达到效果:前台点击按钮弹出文件选择框,选择文件确定之后,上传到后台对文件进行处理并给出响应信息. 尝试过使用$.post,$.ajsx,将表单序列化之后传到后台,但是后台并不能收到文件, ...
- 网页上播放音频、视频Mp3,Mp4
昨天在处理网页上播放音频mp3,视频mp4上用了一天的时间来比较各种方案,最终还是选择了HTML5的 标签,谷歌浏览器.IE浏览器对标签的支持都很好,火狐上需要安装quicktime插件,效果比较差. ...
- 解决无法启动mysql服务错误1069
之前在服务器上修改了my.ini文件 mysql就一直无法启动 后来把my.ini改回原来的,还是无法启动并报1069错误 在网上查了一下,基本上都是说修改mysql密码,再重新启动,试了一下没作用, ...
- Kafka、RabbitMQ、RocketMQ、ActiveMQ 17 个方面综合对比
本文将从,Kafka.RabbitMQ.ZeroMQ.RocketMQ.ActiveMQ 17 个方面综合对比作为消息队列使用时的差异.(欢迎加入Java程序员群:630441304,一起学习交流会) ...
- 基于Python的XSS测试工具XSStrike使用方法
基于Python的XSS测试工具XSStrike使用方法 简介 XSStrike 是一款用于探测并利用XSS漏洞的脚本 XSStrike目前所提供的产品特性: 对参数进行模糊测试之后构建合适的payl ...
- day5-subprocess模块
一.概述 实际应用中,有些时候我们不得不跟操作系统进行指令级别的交互,如Linux中的shell.Python中早期通过os模块和commands模块来实现操作系统级别的交互,但从2.4版本开始,官方 ...
- 在线修改Schema
1. mysql5.5 或者 Mariadb 5.5 之前不需要将数据表中的所有记录复制到临时数据表的操作: a. 修改列名 b. 修改数值类型表示的长度(由INT(2)变成INT(3 ...
- 虚拟机VirtualBox及轻量级的CentOS
1,先下载虚拟机VirtualBox和centos(下边有链接),将VirtualBox安装在本机 2,管理 --> 导入虚拟电脑 --> 选择本地centos文件 3,点击下一步 - ...
- Java--------------Windows下Redis的安装使用
摘要 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted s ...