如何最快速地将旧的 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- ...
随机推荐
- Java循环语句之 do...while
do...while 循环与 while 循环语法有些类似,但执行过程差别比较大. 语法: 执行过程: <1>. 先执行一遍循环操作,然后判断循环条件是否成立 <2>. 如果条 ...
- Class 的继承
简介 Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多. class Point { } class ColorPoint extends P ...
- 基于cornerstone.js的cornerstoneWADOImageLoader
上一篇简单介绍了cornerstone.js的相关使用介绍和基于cornerstone的web库cornerstoneWADOImageLoader,在实际开发中遇到了相关的一些问题,在这里说明一下, ...
- 【Python】更优的字符串格式化方式 -- "format"替代"%s"
背景 前段时间看了一篇介绍Python的代码技巧的文章,建议格式化字符串时使用"format"代替使用"%",但是没有说明原因.各博客网站介绍相关用法的博客很多 ...
- 设置table的td宽度,不随文字变宽
页面中table宽度设置width="600px"之后,宽度仍然不是固定的,文字太长后不换行,把table都撑变形了. 解决办法: table 设置 宽度,绝对宽度和相对都可以 t ...
- ML之多元线性回归
转自:http://www.cnblogs.com/zgw21cn/archive/2009/01/07/1361287.html 1.多元线性回归模型 假定被解释变量与多个解释变量之间具有线性关系, ...
- Java导出Excel(有数据库导出代码)
/** * 导出 * @param request * @param response * @throws Exception */ @SuppressWarnings("unchecked ...
- Qt界面(控件)相关设计
(转自:http://blog.chinaunix.net/uid-25799257-id-600157.html) 引言 最近在做数据库相关课程设计,所以就借此机会,先熟悉一下Qt的一些编程,同时 ...
- SQL Plus常用命令
1.常用命令:显示当前用户名:show user登录到数据库:conn[etc] 用户名/密码@网络[as sysdba / as sysoper] 简单写法:conn 用户名/密码 con ...
- yii2.0 高级版 restful api使用
1.复制任意个目录(backend)为api 2.打开api下的main.php 修改 id=>app-api,'controllerNamespace' => 'api\controll ...