Windows 机密摆脱 DLL 梦魇

Raymond Chen

DLL 梦魇。 问题竟严重到如此境地,甚至于自身都背有这么恶劣的绰号。当您安装某个程序时,另一个看似与之无关的程序忽然停止工作。原因出乎您的意料,这两个程序通过一个共享的 DLL 文件产生了某种联系。它们对于系统目录中应该存在哪种 MSVCRT.DLL 文件版本产生了分歧。或者,一个程序可能会升级另一个程序正在使用的 ActiveX® 控件,而后者对于升级后的控件并不完全兼容。

如果这两个程序在您的公司的日常运作中都是必不可少的,则追究哪个才是罪魁祸首就显得无关紧要。当务之急是要让它们启动并运行。比方说,“我们不断赔钱”和“都怪 Bob,他使我们不断赔钱”,这两种情况并无二样,因为不管是哪一种情况,您的公司都在不断赔钱,立即解决问题对我们而言都责无旁贷。

这个比方常常用来形容非要对程序进行取舍的情况。从 Windows® 2000 开始,系统提供了一些修复工具,可以帮助您处理这些冲突。但是,这些修复工具只是临时性的解决方案,当您研究更为永久的冲突解决方案时,这些工具可以让您的系统恢复到正常状态。

Windows 2000 只附带了一种简单的修复工具,现在拥有一个富有创意的名字,即“动态链接库重定向”。要启用 DLL 重定向,请先创建一个与计划进行 DLL 重定向的程序同名的文件,但需在名称后面加上 .local。例如,要对 C:\Program Files\Litware Inc\Invoice.exe 应用重定向,请创建文件 C:\Program Files\Litware Inc\Invoice .exe.local。文件的内容无关紧要,只要该文件存在即可。

一旦为某个程序启用了重定向,则该程序针对加载 DLL 所执行的所有操作,在查找常规位置之前,将首先查找包含该程序的目录。因此,在 MSVCRT.DLL 文件发生冲突的情况下,您可以在每个程序中启用重定向,然后将 MSVCRT.DLL 的私有副本分别放在它们的安装目录下。每个程序就会获得符合自己版本要求的 MSVCRT.DLL,即程序测试所使用的 DLL 版本。

该技术的魅力在于,即使程序加载 DLL 时使用的是完整路径,该方法也同样有效。例如,假设程序试图加载 C:\Program Files\Common Files\Proseware Inc\taxplugin.dll。在升级到 Proseware 2.0 后,您发现其税款插件与您的发票程序不兼容。您能做的就是将旧版税款插件复制到 C:\Program Files\Litware Inc\taxplugin.dll。即使该程序在加载税款插件时使用的是完整路径,DLL 重定向仍然会在当前目录中查找并使用本地替代的 DLL,而不是 Proseware Inc 目录中的 DLL。

在 Windows XP 和 Windows Vista™ 中,DLL 重定向的规则略有不同,但基本原理是相同的。除创建 .local 文件外,还可以创建 .local 目录。在这种情况下,程序搜索的是 .local 目录,而不是其安装目录。该方法可以在同一目录中对多个程序应用重定向,而不会产生任何冲突。

请注意,无法对包含应用程序清单的程序应用重定向,并且一些所谓的已知 DLL 也不应作为重定向的对象。(有关详细信息,请参阅“Dynamic-Link Library Redirection”(英文)。)

DLL 重定向不可能帮您完全摆脱 DLL 梦魇,但是当您解决这些问题时,它至少会为您提供一些应急的处理方法。

图 1

图 1   

Raymond Chen 正在他的网站上撰写关于 Windows 历史和 Win32 编程的文章,该网站名叫 The Old New Thing(英文),恰巧他的新书也名叫《The Old New Thing》(旧事重提)(Addison-Wesley, 2007)。但这并不意味着“The Old New Thing”就是他的命名习惯。

© 2008 Microsoft Corporation 与 CMP Media, LLC.保留所有权利;不得对全文或部分内容进行复制.