Loadlibrary 加载指定动态库失败的问题解决


这两天在帮公司的一个产品部门解决一个问题, 比较典型,记录一下。问题的背景如下:


该部门的一个测试人员通过install.exe 安装了自己部门的产品, 安装后发现, 出现了一些比较诡异的现象:

1.  直接在安装目录的bin目录下启动exe程序, 可以正常使用;

2.  通过快捷方式启动, 无法正常使用

3.  将对应的项目文件的默认打开程序设为该软件, 也无法正常使用。

并且,这个问题只在这一个人的机器上出现, 机器的操作系统为win10 64位。

 

接着通过初步跟踪发现, 是由于程序在启动另一个辅助进程时, 辅助进程内部需要显式调用LoadLibrayEx 去加载一个动态库, 而上面的后两种情况会导致加载这个动态库失败, 进而导致程序出现异常。

然后我通过GetLastError获取了加载动态库失败时的错误码, 返回的为 126,  因为LoadLibrary加载的动态库路径是由主进程传过来的, 所以第一反应就是路径出问题了, 但是把路径打印出来后, 发现路径没有问题, 但是就是加载不起来。

将126 这个错误码在网上搜了搜, 代表的是找不到指定模块。 但是可以明确的是, 该路径下的动态库包括其依赖的动态库, 在其目录里肯定存在。然后想了想因为这个dll相当于是跨dll调用, 会不会是路径的问题, 然后修改了快捷方式的起始位置, 发现以快捷方式启动程序, 可以正常运行了, 但是双击文件依旧崩溃。

怀疑是注册表里相关的设置导致双击启动时路径出了问题, 便搜索了一下 注册表, 并没有发现异常的地方。到这里依旧没辙了。

于是利用vs远程附加调试, 对比了出错和不出错时, vs输出的动态库加载信息, 发现不出错时加载了vcomp100.dll, 而出错时是没有加载这个动态库的, 尝试把这个动态库拷进辅助进程里, 问题解决。


后来总结了一下几个疑点, 如下:


 

1.       为什么只在某一个人的机器上出现

 

该库为vc系统库,一般装了vs的机器上, dll加载链上的系统目录里都会有的,但是不排除某些人机器上没有,在网上搜了搜,确实有很多人运行其他程序时,也会出现加载该dll失败的弹窗。

 

2.       为啥 右键单击查看文件信息会弹窗提示缺少该dll, 而起主程序却不会?

 

在测试同事的机器上右键单击工程信息并没有出现弹窗,因此不清楚工程信息的实现逻辑,无法判断。

 

但是启动主程序没有弹窗,猜测原因如下:由于出问题的工程都是需要升级的工程,升级是由一个独立的辅助进程执行;

a)        该辅助进程由主程序加载的A.dll启动;

b)        启动过程中需要显式调用LoadlibraryEx 跨目录加载特定版本的dll

c)        dll又会依赖其他很多的dll

 

上面三种结合了以后判断,貌似在这种情况下,如果某个不是直接依赖的dll 出了问题,是报不出来的。我写了个demo测试了一下,也报不出来,只通过GetLastError获得了一个errCode(126)

 

3.       为啥修改了快捷方式的起始位置,增加了bin后, 快捷方式启动就可以正常运行了。

 

快捷方式的起始位置相当于程序启动后的工作目录,而在主程序下存在一个vcomp100.dll

你可能感兴趣的:(C/C++)