如何最快速地将旧的 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- ...
随机推荐
- SQL Server----解决SQL Server 配置管理器不见了
错误重现: 之前安装好的SQL Server 2012打开都没有问题,好多天没有打开了,今天打开我的SQL Server 2012 连接时出现错误: 在与SQL Server 建立连接时出现与网络相关 ...
- 开启Tomcat APR运行模式,优化并发性能
Tomcat支持三种接收请求的处理方式:BIO.NIO.APR 1>.BIO模式:阻塞式I/O操作,表示Tomcat使用的是传统JavaI/O操作(即Java.io包及其子包).Tomcat7以 ...
- 聊一聊Spring AOP
前两天,在给新入职的同事做技术介绍时,讲到spring的AOP.使我又一次认识到,对于AOP,特别是spring AOP的理解,虽然大家都能说上来几句,但是许多人认识并不太全面,甚至可以说是一知半解- ...
- python2 commands模块在python3.x被subprocess取代
subprocess 可以执行shell命令的相关模块和函数有: os.systemos.spawnos.popen --废弃popen2.* --废弃commands.* --废弃,3.x中被移除 ...
- Vue打包上线部署
一.路径问题 1.脚手架+webpack打包通过npm run build,但是后台tomcat部署上线的时候,会衍生出一些问题,比如,路径问题(因为在项目中,我们使用了绝对路径,这里必须要使用相对路 ...
- C++复习15.指针知识
C++复习15.指针知识 4.指针知识 在Tencent 笔试和面试中都考到了 C/C++中的指针知识,因为自己很不喜欢使用指针,所以才开始学习 Java的,但是现在看来还是躲不掉的,所 ...
- Java复习10.Servlet编程
Java复习10. Servlet编程知识 20131008 前言: 之前在大三下的时候,学习了一个月的JSP和Servlet知识,但是没有什么项目经验,把JSP Web开发学习实录看了前面几张,后面 ...
- hdu 4081 Qin Shi Huang's National Road System 树的基本性质 or 次小生成树思想 难度:1
During the Warring States Period of ancient China(476 BC to 221 BC), there were seven kingdoms in Ch ...
- U盘做了一个启动盘来安装Ubuntu,装好后,U盘不能进行格式化了,现在说一下网上找的方法
参考网址:http://wenwen.sogou.com/z/q289778573.htm 说是这种情况需要对U盘进行低级格式化,具体方法如下: 你可以尝试使用diskpart命令 ① 以管理员身份运 ...
- APUE学习笔记——7main()函数启动与退出
程序的启动与退出过程 先上图,了解进程运行的机制. 内核首先调用exec,运行C启动进程,C启动进程会调用main()函数. 其他所有函数都是由main函数直接或间接调用的. ...