之所以想搞明白这个是因为之前写的qt项目release版本和debug版本执行效果不一样
所以想弄明白
主要参考了这个博客,感觉说的比较明白,然后下面是我读自己想要的部分进行提取的
https://www.cnblogs.com/tocy/p/windows_dll_searth_path.html
首先,你的exe文件在编译的时候指定了它需要哪些部分的dll文件,在应用程序加载dll的时候如果加载错(同名)了dll就会报错
接下来的内容是
1. 参考MSDN,给出Windows下DLL查找顺序
2. 简单使用ProcessMonitor来验证DLL查找顺序
1
应用程序可以通过以下方式控制一个DLL的加载路径:
- 使用全路径加载、
- 使用DLL重定向
- 使用manifest文件。
如果上述三种方式均未指定,系统查找DLL的顺序将按照本部分描述的顺序进行
对于以下两种情况的DLL,系统将不会查找,而是直接加载:
对于已经加载到内存中的同名DLL,系统使用已经加载的DLL,并且忽略待加载DLL的路径。(注意对某个进程而言,系统已经加载的DLL一定是唯一的存在于某个目录下。)
b. 如果该DLL存在于某个Windows版本的已知DLL列表(unkown DLL)中,系统使用已知DLL的拷贝(包括已知DLL的依赖项)。已知DLL列表可以从如下注册表项看到:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs。
这里有个比较坑的地方,对于有依赖项的DLL(即使使用全路径指定DLL位置),系统查找其所依赖DLL的方法是按照实际的模块名称来的,因此如果加载的DLL不在系统查找顺序目录下,那么动态加载该DLL(LoadLibrary)会返回一个"找不到模块"的错误。
2. 系统标准DLL查找顺序
系统使用的标准DLL查找顺序依赖于是否设置了"安全DLL查找模式"(safe DLL search mode)。"安全DLL查找模式"会将用户当前目录置于查找顺序的后边。
"安全DLL查找模式"默认是启用的,禁用的话,可以将注册表项HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode设为0。调用SetDllDirectory函数可以禁用"安全DLL查找模式",并修改DLL查找顺序。
Windows XP下,"安全DLL查找模式"默认是禁用的,需要启用该项的话,在注册表中新建一个SafeDllSearchMode子项,并赋值为1即可。"安全DLL查找模式"从Windows XP SP2开始,默认是启用的。
启用"安全DLL查找模式"时,查找顺序如下:
a. 应用程序所在目录;
b. 系统目录。GetSystemDirectory返回的目录,通常是系统盘\Windows\System32;
c. 16位系统目录。该项只是为了向前兼容的处理,可以不考虑;
d. Windows目录。GetWindowsDirectory返回的目录,通常是系统盘\Windows;
e. 当前目录。GetCurrentDirectory返回的目录;
f. 环境变量PATH中所有目录。
如果"安全DLL查找模式"被禁用,查找顺序如下:
a. 应用程序所在目录;
b. 当前目录。GetCurrentDirectory返回的目录;
c. 系统目录。GetSystemDirectory返回的目录,通常是系统盘\Windows\System32;
d. 16位系统目录。该项只是为了向前兼容的处理,可以不考虑;
e. Windows目录。GetWindowsDirectory返回的目录,通常是系统盘\Windows;
f. 环境变量PATH中所有目录。
默认情况下应该是这个:
包含可执行文件的目录。
Windows 的系统目录,该目录可以通过 GetSystemDirectory 得到,一般为 System32 目录,若为 32 位程序跑在 64 位系统下,则为 SysWOW64 目录。
16 位的系统目录,即 Windows 目录中的 System 目录。 Windows 目录,该目录可以通过 GetWindowsDirectory 得到。 进程的当前目录。
PATH 环境变量中所列出的目录。