【转】Windows 8 desktop app中dll搜索路径设置的诡异现象,Bug?

时间:2022-08-26 22:31:28

原文地址:http://blog.csdn.net/my_business/article/details/8850151

某个桌面程序在win 8上运行异常的问题困扰了我有近一周,今天终于找到了根本原因,严重怀疑是win 8的一个Bug。
(所有程序都是desktop app,跟Metro模式无关)
情况是这样的,比如有个Main.exe会通过CreateProcess启动另外一个Sub.exe,而这个Sub.exe中会通过LoadLibrary动态加载多个动态链接库,Main.exe和Sub.exe以及相关dll都不在同一路径,所以在Sub.exe中会通过SetCurrentDirectory来设置dll的搜索路径以保证LoadLibrary可以正常找到dll并加载。这些程序在WinXP,Win7下都运行正常,但是到了Win8下运行时就报出某dll找不到(126)的错误。比较了代码以及一切相关设置都跟Win7完全相同,但dll就是不能正常加载。
 
第一层分析,检查了在Win8下SetCurrentDirectory是否正常工作,发现设置成功,一切正常。然后查了MSDN,windows下dll默认的搜索路径是:
1. 应用程序所在的路径
2. 当前目录(SetCurrentDirectory所设置的路径)
3. Windows SYSTEM目录。通过调用GetSystemDirectory函数可以获取这个目录的路径。
4. 16位系统的目录。并没有函数可以获取这个目录的路径,但是它会被查找。
5. Windows目录。通过调用GetWindowsDirectory函数可以获取这个目录的路径。
6. PATH环境变量指定的路径。
也就是说通过SetCurrentDirectory设置的第二项“当前目录”,在dll检索中没有起作用。那什么API会影响到dll搜索路径呢?
 
第二层分析,发现通过SetDllDirectory这个API可以直接设置dll搜索路径,而通过此API设置后搜索路径就变成:
1. 应用程序所在的路径
2. SetDllDirectory所设置的路径
3. Windows SYSTEM目录。通过调用GetSystemDirectory函数可以获取这个目录的路径。
4. 16位系统的目录。并没有函数可以获取这个目录的路径,但是它会被查找。
5. Windows目录。通过调用GetWindowsDirectory函数可以获取这个目录的路径。
6. PATH环境变量指定的路径。
也就是说如果你使用过SetDllDirectory来设置路径,那即使你再用SetCurrentDirectory来设置当前路径,它也不会属于dll搜索路径中。
 
第三层分析,难道是Sub.exe或者某个dll中调用了SetDllDirectory,搜索了下,一个没有。总不会是Main.exe中有调用从而会影响到Sub.exe吧?搜了下Main.exe的相关代码,确实发现有几处调用了SetDllDirectory。尝试在Sub.exe中通过GetDllDirectory打出该路径,发现不为空,确实是在Main.exe设置过的值。基本确定是原因。
 
第四层分析,那SetDllDirectory的设置怎么会从Main.exe传递到了Sub.exe,查看了调用CreateProcess的第五个参数(关于句柄继承的那项),确实设置成True了,难道这个改下就能解决?立马改成False,再试,还是失败。何况一样的处理在Win7下是正常的,说明肯定有什么特性在Win8下有差异。再回到SetDllDirectory,在Win7下尝试了下,不管CreateProcess的第五个参数设置True还是False,Main.exe中SetDllDirectory的设置都不会传递到Sub.exe,而Win8则相反会传递。
 
第五层分析,那怎么解决呢?尝试了在Main.exe调用CreateProcess启动Sub.exe前,或者在Sub.exe中通过SetDllDirectory(“”)来清除已有的设置,可以解决这个问题。另外比较推荐在所有通过调用SetDllDirectory来设置搜索路径并加载关联dll后马上通过SetDllDirectory(“”)来清除,防止影响到后续的其他处理。
 
目前为止仍旧想不通为什么会有这么恶心的区别。
 
结论:
  1. 这很可能是属于 Win8的一个 Bug
  2. 由于 Win7和 Win8下的这些差异,尽量保证 exe和所关联 dll在同一路径,或者尽量都用绝对路径去调用 LoadLibrary
  3. 如果使用 SetCurrentDirectory来配置 dll搜索路径时,当 exe由其他进程启动时,系统变量或句柄会可能受父进程的影响
  4. 网上还看到可以通过manifest文件来解决,目前还没有尝试。
 

【转】Windows 8 desktop app中dll搜索路径设置的诡异现象,Bug?的更多相关文章

  1. DLL搜索路径和DLL劫持

    DLL搜索路径和DLL劫持 环境:XP SP3 VS2005 作者:magictong 为什么要把DLL搜索路径(DLL ORDER)和DLL劫持(DLL Hajack)拿到一起讲呢?呵呵,其实没啥深 ...

  2. 关于DLL搜索路径顺序的一个问题

    DLL的动态链接有两种方法.一种是加载时动态链接(Load_time dynamic linking).Windows搜索要装入的DLL时,按以下顺序:应用程序所在目录→当前目录→Windows SY ...

  3. 关于指定dll搜索路径

    原文:关于指定dll搜索路径 问题现象 当部分DLL放在子文件夹下,需要指定DLL搜索路径,否则系统将找不到文件 产生原因 系统默认搜索只会在前程序目录并不包括子目录 解决方法 1,使用App.con ...

  4. 关于DLL搜索路径的顺序问题

    DLL的动态链接有两种方法.一种是加载时动态链接(Load_time dynamic linking).Windows搜索要装入的DLL时,按以下顺序:应用程序所在目录→当前目录→Windows SY ...

  5. C和C++中include 搜索路径的一般形式以及gcc搜索头文件的路径

    C和C++中include 搜索路径的一般形式 对于include 搜索的路径: C中可以通过 #include <stdio.h> 和 #include "stidio.h&q ...

  6. Linux 静态库与动态库搜索路径设置详解【转】

    原文地址:http://blog.chinaunix.net/uid-29025972-id-3855495.html 1. 连接和运行时库文件搜索路径的设置 库文件在连接(静态库和共享库)和运行(仅 ...

  7. linux动态库默认搜索路径设置的三种方法

    众所周知, Linux 动态库的默认搜索路径是 /lib 和 /usr/lib .动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两 ...

  8. LaTeX自定义宏包、类文件的默认搜索路径设置方法

      对于自定义的LaTeX宏包与类,在调用时可以通过在命令\documentclass{}与\usepackage{}命令中指定完整路径或者相对路径,这样确实可以调用,但是编译时总是有烦人的警告信息, ...

  9. Linux 静态库与动态库搜索路径设置详解

    转载:http://blog.chinaunix.net/uid-29025972-id-3855495.html 1. 连接和运行时库文件搜索路径的设置 库文件在连接(静态库和共享库)和运行(仅限于 ...

随机推荐

  1. HTML5-WebSocket技术学习&lpar;1&rpar;

    WebSocket是为解决客户端与服务端实时通信而产生的技术. 介绍它是什么的废话不多说了,直接说怎么用: 客户端: 1.创建一个 EventSource 对象 var es = new EventS ...

  2. crontab 不能执行git命令问题备忘

    这问题够隐蔽,折腾了近两个小时. 命令 git checkout tagname 手工执行都正常 但在crontab运行时发现分支一直切不过去. 后来告诉是crontab默认的 path  设置和系统 ...

  3. poj 3728 The merchant(LCA)

    Description There are N cities in a country, and there is one and only one simple path between each ...

  4. STL之使用vector排序

    应用场景: 在内存中维持一个有序的vector: // VectorSort.cpp : Defines the entry point for the console application. #i ...

  5. Ehcart整合百度地图

    最近上班有些时间,学习了一下Ehcart的知识,自己制作了一份Ehcart整合百度地图的示例代码. GItHub地址:https://github.com/TianYanFd/tianjin-powe ...

  6. 转载---JQuery 对 Select option 的操作

    下拉框: <select id="selectID" >         <option value="1">1</option& ...

  7. Java SE之正则表达式四:获取

    /** * * @author Zen Johnny * @date 2018年4月29日 下午4:51:08 * */ package demo.regex; import java.util.re ...

  8. h5的坑

    转自 http://www.mahaixiang.cn 解决各种坑 http://www.mahaixiang.cn/ydseo/1529.html

  9. hdoj 1003 学习思路

    基本解题思路:动态规划,不考虑穷举,分治. 根据网上,状态转移方程是:MaxSum[i] = Max{ MaxSum[i-1] + A[i], A[i]} 翻译公式:到当前位置i 时,最大子序列和为: ...

  10. GitHub 教程【转】

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...