旧工程在原先的版本里是可以正常保护的,但把Agile.NET升级之后,突然会报错、配置项失效或者输出的程序运行不起来,这样的情况其实并不少见。我们在讨论Agile.NET升级版本后配置为什么不兼容、旧工程迁移又该先检查哪里的时候,先不要急着把所有的保护选项重新打开。按官方文档的说法,Agile.net项目会把软件的程序集和保护设置一起保存下来,也可以存成基于XML的项目文件,后续还能通过命令行的工具去运行,这也就是说,旧工程在迁移时,项目文件、程序集的路径、保护项以及构建脚本都会影响到最后的结果。
一、Agile.NET升级版本后配置为什么不兼容
升级之后配置不兼容,一般不是因为某一个单独的按钮失效,而是旧版本的项目文件、保护项的名称、默认的规则、程序集的依赖还有构建环境这些东西发生了变化,先把这些差异拆开来一项一项地看,定位问题就会容易很多。
1.旧项目文件的格式存在差异
Agile.NET的项目文件里面保存了程序集、输出目录、签名文件和各种保护设置,版本升级以后,旧的XML项目虽然还有可能被打开,但是其中一些选项的解释方式已经不一样了,这就导致了界面上虽然显示正常,真正构建出来的结果却跟以前对不上。
2.保护项的默认行为发生了改变
Agile.NET提供了不少保护方式,像代码虚拟化、代码加密、符号重命名、方法调用混淆、字符串混淆、资源加密、程序集合并、控制流混淆和声明式混淆等等,新版本如果把某些保护项的默认强度调整了,那旧工程再直接套原来的配置,就很容易影响到反射、序列化、插件加载或者动态调用这些功能。
3.程序集依赖没有被一起加进去
官方文档建议把组成软件的所有程序集都加到项目里,就算是那些不准备保护的程序集,Agile.net在构建的时候也会把它们复制到输出目录去,要是迁移旧工程的时候只加了主程序,却把公共库、插件库或者第三方的依赖给漏掉了,构建也许能够通过,但真正运行的时候就可能缺少文件,或者类型解析失败。
4.签名和输出路径发生了变化
如果原先的程序使用了强名称签名,Agile.NET在构建时也得用相同的强名称密钥文件去重新签名,升级以后路径变了、密钥文件找不到了,或者输出目录被改动了,都有可能让新生成的程序集和旧的部署包不一致。
二、Agile.NET旧工程迁移时应该先检查什么
在迁移旧工程的时候,最忌讳的就是直接把旧配置导进来,然后点一下构建,更稳妥的做法是先把现有的配置做一个全面的盘点,再从低强度的保护开始,逐步增强,一边做一边验证。
1.先把旧工程和输出包备份好
迁移之前,把旧的Agile.NET项目文件、旧版本保护之后生成的程序集、还没有保护的原始程序集、构建脚本以及发布包都保留下来,这样如果新版本跑出来的结果不对,就可以对比分析一下,到底是保护配置变了,还是应用代码本身发生了变化。
2.仔细核对程序集清单
把主程序、业务DLL、插件DLL、公共的模型层、配置程序集和第三方依赖一个一个地检查一遍,特别是涉及到反射调用、Json模型、WCF接口、COM互操作还有插件入口这些地方,要确认它们是不是需要从重命名保护中排除掉。
3.检查保护项的开关状态
一开始不要把所有保护项全打开,可以先用基础的重命名,或者风险比较低的保护项去构建,然后跑一遍主流程,确定没问题了,再逐步把控制流混淆、字符串混淆、资源加密、虚拟化或者代码加密这些更强的保护加上去。官方文档也是把保护过程划分成多种保护操作配置的,不适合在迁移的时候一次性全部开起来。
4.检查构建脚本里的路径
如果旧工程是用命令行或者CI的方式来构建的,就要重点检查Agile.NET的安装路径、项目文件路径、输入程序集的路径、输出目录还有签名文件的路径,因为在界面上能够成功构建,并不代表在流水线上也能同样顺利地跑通。
三、Agile.NET迁移后怎么确认配置是可用的
迁移结束之后,不能光看构建有没有成功,Agile.net官方的构建流程说明里提到,把保护过程配置好以后点击Build,构建完成就可以打开并且运行保护之后的程序集,也就是说,运行验证才是判断迁移是否真正成功的关键。
1.做一次功能冒烟测试
先把登录、主界面、配置读取、接口调用、数据库访问、文件导入导出这些主要的功能流程跑一遍,只要发现其中有任何一个异常,就不要再继续往上加高强度的保护了。
2.重点测试反射和序列化相关的部分
经过混淆之后,比较容易出问题的地方,通常集中在Json的字段、配置绑定、枚举字符串、接口的DTO对象、插件发现和用反射创建实例这些场景上,在迁移的时候,要准备好固定的测试样例,一项一项地去验证字段名和类型是否还能对得起来。
3.把新旧输出结果放在一起对比
将旧版本保护出来的成品和新版本保护出来的成品,放到同一个测试环境中去比较,检查文件的数量、程序集的名称、签名状态、配置文件、资源文件和运行时的日志,差异点越早被发现,将来需要回滚的时候,付出的代价就越低。
4.把迁移的记录保留下来
记录的内容包括Agile.NET的版本号、旧的项目文件、新的项目文件、排除了哪些东西、保护项开关的状态、签名文件、测试的结论和遗留下来的问题,等到以后再次升级的时候,有这样一份详细的记录,比临时去翻配置要好用得多。
总结
整体来说,Agile.NET升级版本后配置不兼容,常见的原因往往集中在旧的项目文件、保护项的默认行为、程序集依赖、签名路径和构建脚本的变化上面,所以旧工程迁移的时候,应该先查项目文件、程序集清单、排除规则、签名文件还有流水线的参数,然后一步步地打开保护项,做回归性的验证,迁移这件事的本质,并不是把旧配置直接搬过去用,而是要重新确认哪些内容是可以保护的,哪些外部的接口和约定是必须保留不能动的。