转贴:技术聊天《.DLL 动态链接库引起的 Windows 系统故障常见解决方案》
笔者日前受邀于《电脑爱好者》杂志社第 5 会议室参加一场技术聊天,与到会来宾及网友聊了聊与 .DLL 动态链接库有关的一些常见问题,特将部分聊天记录转贴供大家参考。本次聊天亦刊登于《电脑爱好者》杂志 2008 年 04 期,但有较大删改。
前言:
我们平时在使用 Windows 系统及各种应用软件时,经常会遇到与 .DLL 动态链接库有关的各类故障,例如找不到指定的 .DLL 文件、所需的 .DLL 文件损坏等等。由于各种 .DLL 动态链接库通常是 Windows 系统及应用软件的核心组成部分,遇到 .DLL 动态链接库“闹别扭”的时候,往往会引起 Windows 无法启动、需要的应用软件无法正常运行等问题,严重影响了我们的日常工作。这些故障有些是由于 Windows 系统或应用软件自身的损坏引起的、有些是由于恶意程序破坏引起的、有些则可能是人为设置引起的。当遇到 .DLL 动态链接库“闹别扭”的故障时,你该怎么办?今天 Cfan 小编柳絮飞就请 Alexis 及几位嘉宾网友一起来聊一聊这个话题。
出场人物:
柳絮飞、Alexis、Mars、Phobos、Deimos
柳絮飞(主持人):
虽然我们几乎每天都要与 .DLL 动态链接库打交道,但是很多网友对什么是 .DLL 却没有一个直观的概念。Alexis 能否为我们简单介绍一下什么是 .DLL 文件?
Alexis(客座专家):
.DLL(Dynamic Link Library)动态链接库是一种包含有可被多个程序同时调用的代码及数据的库文件,.DLL 文件有助于促进代码的重用和内存的有效利用。例如,Windows 系统文件 %SystemRoot%\system32\COMDLG32.DLL 负责执行与对话框有关的常见函数,我们在大多数 Windows 平台应用软件中看到的“打开文件”对话框都是由 COMDLG32.DLL 生成的。在 Windows 系统中,有很多其它类型的文件是通过 .DLL 实现的,例如 .DRV 文件(驱动程序)、.CPL 文件(控制面板选项)、.OCX 文件(ActiveX 控件)等等。
通过使用 .DLL 文件,应用软件可以实现模块化,由相对独立的组件构成。例如一个财务软件可以按照模块销售,可以在运行时将各个模块加载到主程序中(如果安装了相应模块)。由于模块是彼此独立的,所以软件的加载速度更快,而且模块只在相应的功能被请求时才加载。此外,.DLL 文件的引入可以更容易地将软件更新应用于各模块,而不会影响软件的其它部分。例如,假设一个工资计算程序的税率每年都会更改,当这些更改被隔离到 .DLL 文件以后,我们无需重新生成或安装整个程序就可以应用更新。
网友 Mars(嘉宾):
听别人说,.DLL 文件也属于一种可执行的程序文件了,它和我们平时常说的应用程序文件有什么区别呢?
Alexis:
尽管 .DLL 文件与应用程序文件都属于可执行的程序模块,但它们并不相同。简单地说,.EXE 文件可以直接执行、.DLL 文件不可以直接执行,这是两者最直观的区别。如果从系统角度讲,.DLL 与应用程序之间有两个基本差异:1.应用程序可以有多个同时在系统中运行的实例,而 .DLL 只能有一个实例;2.应用程序可以拥有堆栈、共用内存、文件句柄、消息队列这样的事物,而 .DLL 不能。
柳絮飞:
经过 Alexis 的解释,相信大家对 .DLL 动态链接库已经有了一个初步的认识。可是我们在日常应用中不可能只对 .DLL 纸上谈兵。如果在日常应用中遇到 Windows 系统或应用软件的 .DLL 文件“闹别扭”,引起 Windows 运行异常,或者应用软件运行时提示“找不到所需的 .DLL 文件”等故障,应该如何处理呢?
Alexis:
对于受保护的 Windows 系统 .DLL 文件,建议大家首先查杀恶意程序、排除恶意程序的影响,然后通过 SFC /SCANNOW 命令检测并恢复受保护的系统文件。假如 SFC 无法修复某些丢失或损坏的系统 .DLL 文件,可以考虑修复 Windows 安装。
至于应用软件方面,由于应用软件彼此之间各不相同,一般需要具体问题具体分析。当我们遇到“找不到所需的 .DLL 文件”等故障时,首先要确认当前内存中加载的 .DLL 有哪些、有问题的应用程序需要加载的 .DLL 有哪些,这可以借助第三方软件 Dependency Walker、DLL Explorer 等实现。确定问题出在哪里之后,再考虑通过重新安装应用软件等方法解决问题。例如,我们使用 Dependency Walker 打开了一个应用程序文件,Dependency Walker 立即为我们列出了这个应用程序需要加载的所有 .DLL,应用程序在运行时缺少哪些 .DLL,哪些 .DLL 文件受到了损坏或丢失,可谓一目了然。我们只需根据这些信息手动修复相应的 .DLL 文件即可。
小知识 Dependency Walker
Dependency Walker 是 Microsoft Visual Studio 提供的 PE 模块依赖性分析工具,它可以记录程序使用的所有 .DLL,有助于避免及更正将来可能发生的 .DLL 问题。如果我们安装有 Microsoft Visual Studio,可以在 Program Files\Microsoft Visual Studio\Common\Tools 文件夹找到 Dependency Walker。
通过 Dependency Walker,我们可以实现:1.检查是否丢失 .DLL;2.检查是否存在无效的程序文件或 .DLL;3.检查导入函数和导出函数是否匹配;4.检查是否存在循环依赖性错误;5.检查是否存在由于针对另一不同操作系统而无效的模块。
网友 Phobos(嘉宾):
除了 .DLL 的丢失或损坏,我还经常遇到 .DLL 冲突的问题,Alexis 能否解释一下什么是 .DLL 冲突?
Alexis:
这是一个好问题。所谓 .DLL 冲突是由于 .DLL 的依赖项引起的,如果某个 .DLL 文件需要使用其它 .DLL 文件中的函数,就会创建依赖项,此程序就不再是独立的。Windows 系统的正常运行不就是建立在众多的系统 .DLL 文件共同工作的基础上的么?假设 .DLL 的依赖项遇到了问题,例如 .DLL 文件版本发生了变化、.DLL 文件受到了损坏或丢失,就会引起依赖它的 .DLL 无法正常运行。类似这样的问题通常叫做 .DLL 冲突。这就是为什么有时候一两个 Windows 系统 .DLL 文件遇到问题,就会影响到整个 Windows 系统的正常运行的原因。
网友 Mars:
你刚才说,可以使用 SFC /SCANNOW 修复 Windows 系统 .DLL 文件的故障。那么 SFC 会不会“不小心”用安装光盘中的低版本系统文件修复了高版本的系统文件、引起 .DLL 冲突呢?例如,假设我执行 SFC 时插入了 Windows XP SP1 安装光盘,用 SP1 的旧版文件修复了 Windows XP SP2 系统,这可怎么办?
Alexis:
这个可以放心。SFC 不会用旧版的系统文件修复新版的系统。以你刚才举的例子为例,如果你的系统是 Windows XP SP2,那么 SFC 提示插入安装光盘时就会显示“现在请插入您的 Windows XP SP2 光盘”,如果你依然插入 Windows XP SP1 安装光盘,SFC 将无法继续。
柳絮飞插话:
这只是 Windows 的默认设置,使用特殊方法是可以绕过这个限制的,请参见 2007 年 22 期杂志的“挑战之星”。当然这样做的后果自负,如果用 SP1 版的系统文件修复了 SP2 系统,出现 .DLL 冲突,小编不负责哦。:)
网友 Deimos(嘉宾):
我也想提一个新问题,除了 .DLL 的丢失、损坏以及 .DLL 冲突外,我看很多 .DLL 文件还需要注册和反注册。一提到 REGSVR32 命令我就头大,Alexis 能否解释一下,什么样的 .DLL 需要注册?
Alexis:
一般来说头变大可以增加 MP,恭喜这位网友(开个玩笑)。这个问题是这样的,对于那些可以自行注册的对象链接和嵌入(OLE)控件(例如 .DLL 文件或 ActiveX 控件),我们可以使用 REGSVR32 命令手动注册或手动取消注册。使用方法很简单,REGSVR32 命令加需要注册的文件名,可以实现手动注册;如果再加上一个 /U 参数,可以取消注册。例如 REGSVR32 %SystemRoot%\system32\VBSCRIPT.DLL,REGSVR32 /U %SystemRoot%\system32\VBSCRIPT.DLL。
需要注意的是,不是所有的 .DLL 动态链接库都可以直接注册的,大多数 .DLL 都是通过导出函数提供功能,只有那些遵循 COM 的 .DLL 才能通过 REGSVR32 注册。
网友 Phobos:
你刚才说过,.CPL 控制面板文件也是通过 .DLL 实现的。我有一次遇到一个奇怪的问题,在 Windows XP 的控制面板中打开“用户帐户”时,发现“用户帐户”的所有选项都消失了,整个窗口一片空白。我执行 SFC /SCANNOW,没有检测到问题,这是不是就是相应的 .DLL 文件没有注册引起的?
Alexis:
是。这个问题我也遇到过,解决方法就是首先通过 SFC /SCANNOW 确定系统文件没有任何问题。然后使用 REGSVR32 命令重新注册一下系统文件 JSCRIPT.DLL、MSHTML.DLL、NUSRMGR.CPL、THEMEUI.DLL、VBSCRIPT.DLL,问题即可解决。
网友 Deimos:
最后我还有一个问题。做为一名电脑爱好者,我平时经常安装、卸载各种各样的应用软件。由于软件自身 BUG 或其它原因,常常造成软件卸载时相关文件并未能彻底删除,遗留下大批无效的 .DLL 文件。日积月累,使我的系统越变越大,运行速度越来越慢。有没有什么方法可以清理掉这些无效的 .DLL 文件?
Alexis:
网上有不少专门清理无效 .DLL 文件的专用工具,例如《DLL 清道夫(Analogx DLL Archive)》。在《DLL 清道夫》的主界面中,我们点击“Search”进行搜索即可。《DLL 清道夫》可以快速搜索硬盘中的所有 .DLL 文件,并对其进行有效性校验,最终为我们列出有问题(失效)的 .DLL 文件以便清理。所谓清理并不是删除,而是将这些文件暂时隔离至一个特殊文件夹,日后如果发现系统运行一切正常,再将它们删除;或者如果发现系统运行有问题,可以随时有选择地恢复。
柳絮飞:
OK,今天我们暂时先聊到这里。感谢 Alexis 及各位嘉宾的支持,我们下次再见。