1.自动更新的下载功能只在开发机上可以正常运行,在其他非win10系统上会出现异常
开发机上的下载更新功能正常,但是在两台win7和一台win8.1机器上测试时总是出现上图的现象。弹出的窗口表示触发了自定义的异常处理机制,下载器在初始化时出错了。下载器使用的是迅雷云开放平台提供的动态链接库,因为要在C#中调用动态链接库中函数,直接使用DllImport使用没成功,自己用VC++写了一个动态链接库把迅雷云开放平台的动态链接库包装了一下。这个异常提示看不出什么有用的信息,把异常处理代码去除后又测试了一下(原谅我这种脑残般的操作),这次变成下图这样的提示:
貌似是个内存错误,不过依然不知道什么问题,捉急!那个经典疑问又来了:在我电脑都好好的呀!
其实这个时候应该意识到是自己写的动态链接库问题,但是当时反应还是慢了一步。先是在网上百度了一番,未果。然后又以“VS2015编写的Dll怎样在win7上使用”为关键字百度了一番,各种答案,众说纷纭,有的说需要修改项目配置属性,有的说需要安装VC++ 2015 Runtime,各种答案都有。死马当活马医,先安装vc++ 2105 runtime试试,结果失败。然后又对照一个答案修改如下图项目属性里的若干配置:
一通配置过后,再试,直接编译不通过,报一堆错,见下图:
看到这个错误数量,我也是无语了。还有人说要把动态库dll改成静态库lib,但是查了一下貌似C#无法直接使用静态库lib。
冷静一下,仔细观察了一下。项目配置属性页里的目标平台版本和平台工作集分别是8.1和V140,难道和这个有关系?8.1是指这个生成的dll文件只能工作在win8.1及以上系统中?
试着选择其他平台版本,无奈8.1是最低的。后面的平台工作集也只有两个选项另一个选项在之前的试验中已经试过不起作用。
看来得试试安装其他平台工作集,但是这个平台工作集无法单独安装。只有安装相应版本的VS,才能获得对应的平台工作集。虽然麻烦,但是值得一试。先装个VS2010试试,安装完成后,平台工作集中多处两个选项,见下图
多出1个V100和V90。其他配置保持不变,选择V100然后编译,没有error和warning,顺利通过。然后在两台win7和一台win8.1专业版测试机上替换掉对应的dll文件再次启动程序,这次没有异常出现,下载更新功能正常,问题似乎顺利解决。
还有其他的解决办法吗?
上图是一开始的项目配置,平台工作集是V140,配置为debug,运行库是多线程调试DLL(/MDd)。这个配置情况下,编译没问题,但是在win7和win8.1的测试机上无法正常工作。
在保持其他项目配置不变的情况下,将平台工作集改为v100后编译生成的dll文件在测试机上可以正常运行。这是我上面所使用解决办法。现在介绍另一种解决办法,无需安装其他平台工作集,只需更改项目配置即可。
在保持平台工作集为V140的情况下,将配置改为Release,运行库改为多线程(/MT)。重新编译生成dll文件,这时会发现dll文件相较之前的变大了。将dll放到测试机上运行功能正常,程序正常运行。
如果没有修改项目编译配置为Release,而只修改了运行库,是会编译出错的。
为什么会这样呢?让我们回到一开始的配置debug、V140、多线程调试(/MDT)。然后利用Dependency Walker查看依赖库,在开发机器上是这样的:
在其中一台win7测试机上是这样的:
可以看到,在win7机器上,除了第一个kernel32.dll依赖库以外,其他3个依赖库都没有!
然后我们把平台工作集修改为V100,再次生成dll然后使用工具查看,开发机器结果如下图:
依赖库有所改变,4个变为3个。
Win7测试机的情况如下图:
可以看到,这次所需的依赖库都有。
然后,将平台工作集改回V140,编译配置改为Release,代码生成改为多线程(/MT),用工具查看dll所需的依赖库如下,可以看到现在依赖库只剩下一个kernel32.dll,但是相应的,生成的dll文件体积增大到108kB。这中间发生了什么,还不清楚。
win7测试机上使用工具查看依赖库的结果如下图:
由上面的分析可知,以debug模式编译,修改平台工作集可解决问题,但是目标机器需要有另外两个依赖库;以release模式编译并修改生成代码运行库也可解决问题,并且目标机器只需有kernel32.dll即可,这是windows系统自带的。所以建议使用第二种解决方案。