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

 DLL的动态链接有两种方法。一种是加载时动态链接(Load_time dynamic linking)。Windows搜索要装入的DLL时,按以下顺序:应用程序所在目录→当前目录→Windows SYSTEM目录→Windows目录→PATH环境变量指定的路径。

 

    前天看到这几句,突然设计出一道自认绝妙的笔试题:

“如果采用加载时动态链接的方式,Windows搜索要装入的DLL采用怎样的顺序?”

这个是基础题,估计你很容易答出(答案就是上面的)。呵呵,我还有后着呢:

“你是如何证明Windows搜索要装入的DLL遵循这样的顺序呢,说出你的证明步骤”

 

     你可以思考一下。下面是我设想的一个方案,但是自己测试了一下。结果却令人吃惊。

我的证明步骤是这样的:

1.     首先新建一个MFC 常规DLL工程OutputModulePath,在里面添加一个API函数,功能就是打印DLL所在路径,然后将其导出,代码如下:

复制代码
void  PaintModulePath()
{
    
extern  COutputModulePathApp theApp;
    TCHAR szModulePath[MAX_PATH];
    :: GetModuleFileName(theApp.m_hInstance,szModulePath, MAX_PATH);
    AfxMessageBox(szModulePath);
}
复制代码

2.     编译这个DLL工程,然后将生成的DLL文件OutputModulePath.dll复制到当前目录、Windows SYSTEM目录→Windows目录→PATH环境变量指定的路径。这里要说明一下:如果调试运行的话,当前目录应该是当前目录的工程文件所在的路径,如果单击直接运行的话,当前目录应该是exe程序所在的路径,具体可以通过一下代码获取当前目录:

复制代码
       TCHAR szBuf[MAX_PATH];
    ::ZeroMemory(szBuf,MAX_PATH);
    
if  (::GetCurrentDirectory(MAX_PATH,szBuf)  >   0 )
    {
     
// 获取进程目录成功。
       AfxMessageBox(szBuf);
     }
复制代码

 

    PATH环境变量指定的路径这里可能有多个路径,这里只须将OutputModulePath.dll拷贝到其中之一就行,例如我拷贝到的是:D:\Program Files\Lua\5.1

 

3.     建一个测试工程(对话框程序或单文档程序都可以),在里面调用PaintModulePath函数。

     我的测试步骤及结果是这样的,按F5调试运行测试程序,首先程序输出的是exe程序所在的路径,然后我将exe程序路径下的dll文件删除,但接着输出的是C:\WINDOWS\system\OutputModulePath.dll,我将C:\WINDOWS\system\OutputModulePath.dll删除,接着输出的是C:\WINDOWS\ OutputModulePath.dll,将C:\WINDOWS\ OutputModulePath.dll删除,输出的才是当前目录下的文件路径,最后输出的是PATH环境变量指定的路径。

 

     这样的结果和书上的理论不符。难道我的测试方案有什么不对吗?

 

     到论坛一问,得到一个答案是微软上的一篇文章:

 

Dynamic-Link Library Search Order

 

     现在把它翻译一下:

 

                                动态链接库的搜索顺序

 

      一个系统可以包含多个版本的同一个动态链接库(dll)。应用程序能够通过使用动态链接库重定向清单文件指定要加载的DLL的全路径。如果没有使用这些方法,这篇文章将讲述在装入DLL时DLL的搜索顺序。

 

标准的搜索顺序

 

    DLL的搜索顺序取决于是否安全DLL搜索模式是启用或禁用。

安全DLL搜索模式在默认状态下是启用的。通过创HKLM\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode注册表项并将它的值设为0可以关闭这个属性。通过调用SetDllDirectory函数可以有效禁用安全DLL搜索模式而在这篇文章中这个函数指定的路径将加入搜索范围并改变搜索顺序。

 

    Windows XP and Windows 2000 with SP4:  安全DLL搜索模式在默认状态下是禁用的。通过创HKLM\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode注册表项并将它的值设为1可以启用这个属性。安全DLL搜索模式在默认状态下得到启用始于带sp2的Windows XP。

 

Windows 2000:  并不支持安全DLL搜索模式。在这种情况下DLL的搜索顺序和安全DLL搜索模式被禁用的情况下的顺序是一样的。安全DLL搜索模式得到支持始于带sp4的Windows 2000

 

假如安全DLL搜索模式启用,搜索顺序如下:

1. 应用程序所在的路径

2. Windows SYSTEM目录。通过调用GetSystemDirectory函数可以获取这个目录的路径。

3. 16位系统的目录。并没有函数可以获取这个目录的路径,但是它会被查找。

4. Windows目录。通过调用GetWindowsDirectory函数可以获取这个目录的路径。

5. 当前目录

6. PATH环境变量指定的路径。请注意,这并不包括每个应用程序的应用程序路径注册表项中指定。在应用程序路径注册表项的键值并不作为DLL的搜索路径。

 

 

假如安全DLL搜索模式禁用,搜索顺序如下:

1. 应用程序所在的路径

2. 当前目录

3. Windows SYSTEM目录。通过调用GetSystemDirectory函数可以获取这个目录的路径。

4. 16位系统的目录。并没有函数可以获取这个目录的路径,但是它会被查找。

5. Windows目录。通过调用GetWindowsDirectory函数可以获取这个目录的路径。

6. PATH环境变量指定的路径。请注意,这并不包括每个应用程序的应用程序路径注册表项中指定。在应用程序路径注册表项的键值并不作为DLL的搜索路径。

 

预备的搜索顺序

 

      由系统指定的标准搜索顺序可以通过调用LoadLibraryEx函数加上LOAD_WITH_ALTERED_SEARCH_PATH参数值得到改变。标准搜索顺序也可以通过调用SetDllDirectory函数得到改变。

 

     Windows XP:  通过调用SetDllDirectory函数来改变标准搜索顺序并不支持直到Windows XP sp1出现。

     Windows 2000: 不支持通过调用SetDllDirectory函数来改变标准搜索顺序。

 

 

如果您指定一个备用的搜索顺序,程序将按备用的搜索顺序进行搜索,直到所有相关的可执行模块被找到。系统启动后,DLL初始化例程处理,该系统将恢复为标准的搜索顺序。

 

LoadLibraryEx函数通过指定LOAD_WITH_ALTERED_SEARCH_PATH属性和lpFileName参数指定一个绝对路径支持一个预备的搜索顺序。

 

请注意:标准搜索顺序和通过调用指定LOAD_WITH_ALTERED_SEARCH_PATH属性的LoadLibraryEx函数来设置的预备搜索顺序只是有一点不同:标准搜索顺序开始于搜索1. 应用程序所在的路径而预备搜索顺序开始于LoadLibraryEx函数所要加载的可执行模块的所在目录。

 

   假如安全DLL搜索模式启用,搜索顺序如下:

1. lpFileName参数值所指定的目录

2. Windows SYSTEM目录。通过调用GetSystemDirectory函数可以获取这个目录的路径。

3. 16位系统的目录。并没有函数可以获取这个目录的路径,但是它会被查找。

4. Windows目录。通过调用GetWindowsDirectory函数可以获取这个目录的路径。

5. 当前目录

6. PATH环境变量指定的路径。请注意,这并不包括每个应用程序的应用程序路径注册表项中指定。在应用程序路径注册表项的键值并不作为DLL的搜索路径。

 

 

假如安全DLL搜索模式禁用,搜索顺序如下:

1. lpFileName参数值所指定的目录

2. 当前目录

3. Windows SYSTEM目录。通过调用GetSystemDirectory函数可以获取这个目录的路径。

4. 16位系统的目录。并没有函数可以获取这个目录的路径,但是它会被查找。

5. Windows目录。通过调用GetWindowsDirectory函数可以获取这个目录的路径。

6. PATH环境变量指定的路径。请注意,这并不包括每个应用程序的应用程序路径注册表项中指定。在应用程序路径注册表项的键值并不作为DLL的搜索路径。

 

假如lpPathName参数指定了一个路径,SetDllDirectory函数支持一个预备的搜索顺序。这个预备的搜索顺序如下:

1. 应用程序所在的路径

2. lpPathName参数指定的目录

3. Windows SYSTEM目录。通过调用GetSystemDirectory函数可以获取这个目录的路径。

4. 16位系统的目录。并没有函数可以获取这个目录的路径,但是它会被查找。

5. Windows目录。通过调用GetWindowsDirectory函数可以获取这个目录的路径。

6. PATH环境变量指定的路径。请注意,这并不包括每个应用程序的应用程序路径注册表项中指定。在应用程序路径注册表项的键值并不作为DLL的搜索路径。

 

如果lpPathName参数为一个空字符串,当前目录将会从搜索顺序中删除。

SetDllDirectory 有效地禁用安全DLL搜索模式,而在搜索指定的目录路径。要恢复安全 DLL搜索模式的SafeDllSearchMode注册表值的基础和恢复当前目录到搜索顺序,调用 lpPathName的参数值为NULLSetDllDirectory函数。

 

    看完这篇文章,我大致知道了我的测试为何会出现那个结果,因为我的操作系统环境是Win XP + sp3。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: debug.exe是Windows系统中的一个命令行工具,主要用于调试应用程序或操作系统。debug.exe并不是一个官方发布的独立软件,而是随着Windows操作系统一起提供的。 在CSDN(中国软件开发者社区)上下载debug.exe并不可行,因为CSDN主要是一个面向开发者的知识分享平台,提供了众多软件开发相关的教程、资源和论坛等。但是像debug.exe这样的操作系统内置工具,通常不会在CSDN上提供下载。 如果你需要获取debug.exe,可以通过以下几种途径来获得: 1. 通过Windows操作系统安装盘或官方镜像:debug.exe是Windows操作系统的一部分,当你安装或重新安装Windows时,它应该会随之一同安装。 2. 通过Windows开发者工具包(Windows SDK):Windows开发者工具包是用于Windows平台软件开发的一套工具,其中包含了一些常用的工具,如debug.exe等。你可以前往微软官方网站下载并安装Windows SDK,然后从中获取debug.exe。 3. 从他人或其他可靠的网站获取:在互联网上,你可能会找到其他网站或个人分享了debug.exe或Windows操作系统的内置工具。在获取时请注意确保来源的可信度,并对下载的文件进行杀毒检查。 总之,debug.exe是Windows操作系统的一部分,通常不会在CSDN上提供下载。你可以通过Windows操作系统安装盘、Windows开发者工具包或其他可靠来源来获取debug.exe。 ### 回答2: debug.exe是一个用于调试程序的工具,可以在开发过程中帮助开发者找出程序中的错误并进行修复。关于debug.exe的下载路径,我们可以在CSDN(中国软件开发网)上找到它。 1. 首先,打开浏览器并访问CSDN的官方网站。 2. 在网站的搜索栏中输入"debug.exe"。 3. 在搜索结果页面中,可能会得到很多关于debug.exe的相关内容,我们需要筛选出下载路径。 4. 可以根据搜索结果的排序方式选择按照时间或者相关度排序。通常,时间排序可以确保我们得到最新的、最可靠的下载链接。 5. 在搜索结果中找到一篇包含debug.exe下载链接的文章或者帖子。可以根据标题或者内容预览进行选择。 6. 点击下载链接,可能会弹出一个下载页面。根据指示进行操作,可能需要进行登录或者其他验证过程。 7. 一旦验证完成,debug.exe的下载将开始。可以选择保存文件到自己的电脑上,通常会默认保存到下载文件夹中。 需要注意的是,下载debug.exe路径可能因为时间、网站更新等原因而有所变化。如果以上步骤无法找到最新的下载路径,可以尝试使用其他开发者社区的网站或者搜索引擎进行查询获取。同时也要谨慎下载,确保文件的来源可靠,以避免下载并运行恶意软件。 ### 回答3: 在CSDN不同资源页面上,可以找到debug.exe的下载路径。首先,打开CSDN的官方网站。在主页上,可以看到网站的搜索框,输入"debug.exe"进行搜索。 在搜索结果页面上,可以看到各种与debug.exe相关的资源、博客、问答等。点击其中的一个资源链接,进入资源详情页。 在资源详情页上,可以看到资源的详细描述、截图、标签等信息。同时,在页面的右侧或下方,会有一个下载按钮或链接,点击它即可进入debug.exe的下载页面。 在下载页面上,可以看到debug.exe的具体信息,如版本号、文件大小等。通常会有一个下载按钮,点击它即可开始下载debug.exe文件。 下载过程可能需要一定时间,取决于网络状况和文件的大小。下载完成后,可以打开文件所在目录,找到下载好的debug.exe文件。 总结来说,在CSDN上下载debug.exe路径为:CSDN官方网站 -> 搜索搜索"debug.exe" -> 进入资源详情页 -> 找到下载按钮 -> 点击下载按钮 -> 下载debug.exe文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值