dnSpy调试金蝶云星空的宿主IIS及其局限性

金蝶云星空供应链领域销售模块下集成了快递100和快递管家接口对接,研发平台由于网络安全限制,无法访问快递100和快递管家接口,因此无法利用Visual Studio调试接口代码,一般是将元数据及程序集构建好后将打包文件发布成外网临时补丁,再到有网络权限的外网服务器(这种测试服务器仅仅只是一个能访问公网且安装了IIS的服务器,不会安装Visual Studio)安装补丁才能测试,这种未经过调试就发布到IIS再测试接口对接情况就容易导致很多问题,且测试发现问题也不好定位。因为没有Visual Studio调试清晰。这个时候dnSpy就作用大了,一般我也是用它来代替VS调试代码的,本文将介绍dnSpy这款优秀的反编译工具如何调试IIS,并根据需要输出一些变量值来确定快递100或快递管家相关接口是否正常,以下以管家订单导入接口为例。
首先,查询IIS进程ID,CMD进入C:\windows\system32\inetsrv目录,使用命令appcmd list wp 输出IIS所有站点及站点下挂载的应用程序,其中的应用程序K3Cloud(使用的应用程序池为K3Cloud)对应的ID'17852'就是dnSpy要附加的进程ID, 如下图1-1所示:

图1-1
打开dnSpy,附加进程‘17852'’,如下图1-2所示:

图1-2
针对上面的查询哪个进程是金蝶云星空系统的,其实也可以简单地从命令行参数中查到,这样就不用命令行 appcmd list wp 查询了,直接查询w3wp.exe进程且命令行参数中有K3Cloud就是要附加调试的进程,如下图1-1.2所示:

图1-1.2
找到对应的快递100相关组件,快递100和快递管家对接的相关功能是通过动态表单‘获取电子面单’实现的,其对应的表单插件在程序集文件'Kingdee.K3.SCM.Sal.Business.PlugIn.dll'中,通过菜单‘调试’->‘窗口’->‘模块’可以加载或搜索到此程序集(如果在模块搜索不到此程序集,比如重启IIS后,需要通过登录金蝶云星空系统打开一下‘获取电子面单’功能菜单,此时程序集即可搜索到,这可能是由于IIS基于性能原因或用到才加载的原因,没有将程序集加载到类似以下目录C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\中,也有可能与星空框架有关,它是插件模式,只有用到了才加载该插件),如下图1-3所示:

图1-3
定位到类‘Kingdee.K3.SCM.Sal.Business.PlugIn.GetKuaidiBillEdit, Kingdee.K3.SCM.Sal.Business.PlugIn’中的方法‘OrderImport()’,此方法是’获取电子面单‘中的‘管家订单导入‘ 的核心方法,在最后语句打上断点,如图1-4所示:

图1-4
操作星空系统上的‘获取电子面单’,选择一个单据,然后点订单导入,此时断点进入,图中可以看到一些变量的值,如下图1-5所示:

图1-5
但是大部分情况下,调试IIS会发现变量输出不了,而且有些代码点中的断点根本打不了或者调试的执行顺序容易乱跳,特别是在有抛异常的情况下,这是因为星空发版后的程序集是Release模式构建的,代码优化后变量输出就是一个问题,程序抛异常后也没有像Visual Studio调试那样清晰看到异常详情,上图1-5中能够输出快递管家订单导入接口的数据包是因为我用源代码在Debug模式重新编译且替换了最开始在IIS里面挂载的Kingdee.K3.SCM.Sal.Business.PlugIn.dll程序集(这个源代码只有金蝶总部有,客户二开的话只能看到反编译的代码,且我DEBUG模式重新编译生成的组件版本为1.0.0.0,这和IIS里面的程序集版本是不同的),然后重启了IIS。如果此时想要在Release模式生成的程序集中调试时显示被优化后的变量值,则可在对应的组件目录中添加同名的后缀为ini的文件,.ini文件内容为:
[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0
要注意的是,如果要调试每个加载进Temporary ASP.NET Files 目录下的应用程序集dll文件,则对应的文件都要添加同名的 .ini文件,客户在复制上面的.ini文件内容时要手动删除空格及换行再重新输入空格和换行,这是因为HTML页面会转义空格的原因,目录结构和文本内容如下图1-5.1所示:

图1-5.1
但要注意这个.ini文件不是放在金蝶云星空安装目录 X:\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin 下,而是放在IIS加载应用程序集后目录下,目录一般为C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\k3cloud\7e965141\f7b8376d\assembly\dl3\ba31cdbb\00df3b7e_628ad701,其中k3cloud后面的目录名可能与我的目录是不一样的,每次重启IIS应该也是不一样的,具体目录可通过dnSpy附加进程后双击模块里的程序集显示出来,如下图1-5.2所示:

图1-5.2
下图1-5.3所示为加上.ini文件后Release版本原封不动的组件调试图,其版本号还是星空通版的版本号,它不是像图1-5那样用DEBUG模式编译后现替换组件。可以看到在.ini文件帮忙下,它可以显示出BOS平台底层的DynamicObject数据包对象里的不同字段值,这对调试IIS是非常有作用的。

图1-5.3
如下图1-6就是没有加上.ini文件Release解决方案配置生成的BOS组件调试图(本质上就是云星空系统寄宿在IIS下的最原始版本组件),可以看到方法中的很多变量输出不了。

图1-6
假设当前程序集Kingdee.K3.SCM.Sal.Business.PlugIn.dll是Release模式生成的且没有添加同名.ini文件,那么图1-5中的断点很可能是输出不了调试管家订单导入接口的数据包(方法中的postData), 如果接口有问题,如何排查,一般是通过修改程序集并替换到星空安装目录,然后重启IIS,再进行调试。这里就不那么复杂,直接演示一下如何修改程序集,
dnSpy调试金蝶云星空的宿主IIS及其局限性
声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。



