解决 Delphi BPL 包问题,其中 BPL 无法加载但已经重新编译(Windows VirtualStore 文件系统问题)

12
我的一般问题是如何解决“由于一个依赖项无论我如何清理和重新编译都无法消除,导致我的BPL无法加载”的情况。 更新 你可能认为你有一个干净的重新编译过的系统,但由于反奇迹——Windows及其文件系统虚拟化失误功能,你并没有。
当我尝试将我的设计时包(在这种情况下命名为dclFsTee.bpl)加载到我的Delphi IDE中(它是快速报告4 teechart包装器组件包),它会抱怨:
The program can't start because tee7100.bpl is missing from your computer. Try reinstalling ...

我知道的情况下,我的系统中没有任何DCP或DCU文件引用tee7100.bpl。但很明显出现了问题,我找不到原因。

所有Delphi用户都会遇到一百个关于BPL的“编译失败或无法加载”问题。当被问及该怎么办时,普遍的建议是清理计算机。

然而,我已经花了几个小时来清理我的计算机,尽管一切都编译正常,显然还有一些过时的东西藏在某个地方,因为我正在尝试加载的结果BPL文件仍然想要加载我数天前从此系统中移除的TeeChart BPL版本,以及我能找到的每一个痕迹。

我删除的Delphi 2007中的TeeChart内容包括$(BDS)\Lib和$(BDS)\Lib\debug文件夹中的所有内容,以及系统上所有的DCP和BPL文件夹。此外,命名为TeeChart单元的dcu文件也被删除了。

一旦你到了路的尽头,下一步该怎么做?(格式化硬盘,购买新电脑。)说真的,我认为自己很聪明,但我有一个1TB的硬盘,一个包含80多个文件夹的库路径和一个看起来组织良好的源代码仓库,但显然有些东西隐藏在我找不到的地方。
我拥有TeeChart Standard 2012,带有完整的源代码,据我所知,我的开发机不再包含任何旧的TeeChart BPL或DCP文件,这些文件来自于Delphi附带的“tee chart tee7100.bpl”版本。
我运行了随TeeChart提供的“recompile.exe”向导,它似乎只运行MSBuild并构建软件包,在tee.inc文件中编写{$DEFINE x}声明(源分发中有两个文件)之后。
然而,不知何故,似乎其中一个软件包的隐式导入正在引入一些未重建的过时文件,并因此尝试加载tee7100.bpl。新的BPL名称是tee911.bpl。
不是在问很特定的fastreport问题,我只提到它作为我在使用Delphi开发时面临的许多问题的普遍例子。我只是提供fast-report的细节,以便您可以看到这实际上是Delphi IDE中处理组件源代码或包或一组有依赖关系的包时所面临的一般问题的一个特定例子。清理计算机以使您的代码甚至能够构建可能会很棘手。 因此,这里是我的Delphi包对包依赖项解决方案问题:
1.找到或跟踪隐式加载某些不再需要的BPL问题的最有效方法是什么,以便我的代码(构建和编译良好!)实际加载到Delphi IDE中。由Recompile生成的BPL文件似乎与正确的DCP文件链接正确,并且没有旧/过期的DCP或DCU文件存在。新的DCP文件名称例如为tee911.dcp。
2.您是否可以以某种方式获取任何想法,哪个包实际上已过时,以及在.bpl链接时静态读取、链接和导入了什么?(例如,我想到了BPL文件的特殊MAP文件之类的东西)。 更新 经过多个小时的尝试和使用我所知道的所有技巧,我意识到我没有检查由Windows 7中的文件虚拟化引起的一些VirtualStore相关问题。这意味着Windows 7欺骗运行在其上面的程序。它会给你另一个版本的文件,而不是你想要的那个。这可能有几种致命的影响;其一:重新编译BPL文件,但加载的不是你想要的那个。折磨我的BPL文件位于SysWow64文件夹中,该文件夹是VirtualStore的一部分。请注意,VirtualStore基本上会出现幻影文件,只有当您是某个“低权限”程序时才会出现这些文件,Delphi 2007在Win7/64位上显然是这样的。要删除当前用户帐户下SysWow64 VIRTUALSTORE文件夹中的BPL文件:
   del %HOMEPATH%\AppData\Local\VirtualStore\Windows\SysWow64\*.bpl

有些日子我只是讨厌Windows架构。无论如何,我不会把上面的内容作为答案,因为我想知道是否有更好的方法或任何提示或建议,可以在下次帮助。


是的,设计时从我刚刚重新编译的源代码中加载BPL,但它必须正在拉取一些陈旧的内容,我就是找不到... - Warren P
2
当我在我的工作系统上安装FR时,我总是手动编译/安装软件包,逐个从源代码安装,有时如果出现问题还需要编辑源代码。是的,这需要时间。 - kludg
1
有趣。我猜FR安装程序将这些bpl文件放到了Windows系统目录中 - 另一个不使用组件安装程序的原因。 - kludg
1
发生的情况是BPL位于要由Windows虚拟化的文件夹列表中。尝试排除BPL扩展名进行虚拟化。LUA文件虚拟化过滤驱动程序在注册表HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Luafv\Parameters\ExcludedExtensionsAdd中。您可以在此处添加BPL扩展名(不带点),并尝试是否解决了问题。 - Hendra
1
问题的原因是来自Steema(TeeChart)的安装程序和FastReport的recompile.exe实用程序。它们一起创造了一个完美的糟糕局面,因为它们喜欢在系统目录和“Program Files”文件夹中安装东西,这两个地方我不希望我的Delphi组件安装源代码或二进制文件。我真的很讨厌那种做法。以至于我会剥离掉他们所有的恶意垃圾,只从我自己的来源进行安装。但是获取源代码的初始副本需要运行他们的恶意安装程序,这会导致VirtuaStore混乱。 - Warren P
显示剩余8条评论
3个回答

12

好的,因为没有其他人回答,所以我会在这里提供一些有用的信息:

-- 当清理出现旧版本DLL的破损系统时,请记住Windows VirtualStore,其中包括TeeChart、FastReport、Indy等等。它们往往涉及到混乱,因为它们既可以存在于“随Delphi一起发布的开箱即用包”中,也经常作为升级版本安装,如果您直接从供应商那里购买并安装,则第三个可能是您自己编译的副本,在公司的超级组件包目录中。

-- 当搜索重复或过时的BPL时,在Windows中进行文件搜索不会查找虚拟存储区。您需要手动定位并删除进程、用户或程序的整个虚拟存储区域。

这个问题的第二个层面是:

FastReports的依赖关系图很复杂:

  • 它依赖于Indy,您可能有自己的版本,而Delphi本身也有一个版本,硬盘上的其他东西可能也有它们自己的Indy副本。

  • 它支持各种版本的TeeChart,包括与Delphi一起提供的二进制文件,以及您可能从Steema购买的标准版或其他购买版本的TeeChart。

  • 它使用一个预编译头包含文件进行编译,而不仅仅是一个具有相同名称的包含(.inc)文件,而是两个不同的副本。

  • 当您使用他们自己的编译器工具(重新编译FastReport)时,它能够可靠地工作,但是当您想从单个构建脚本中构建项目中的所有内容时,它并不是最好的选择,这就是我的问题所在。

  • 关键是了解您巨大的软件包堆栈中所有组件的依赖关系,并使系统整洁地组织,以便您不必保留旧版本的东西(如Indy和TeeChart bpls、dcp或dcu文件)。如果您不知道该怎么做,清理起来会非常复杂。

    • 一个清理工具非常重要,以确保彻底删除与您的系统一起提供的Indy和TeeChart版本,以及FastReports的“Embarcadero版”,这是解决这种情况的关键。一个通用的提示是:“如果一个X版本随Delphi一起发布,而你将要安装一个新版本,请准备好遭受痛苦,直到你的系统真正被清理干净”。

    • 一个非常棒的技巧是在初次安装Delphi IDE时不要安装Indy、FastReport或TeeChart(取消勾选它们或跳过它们),然后从源代码自行逐个安装它们。仅仅因为一个版本预先安装在Delphi中并不意味着那是一件好事。(更新:自至少Delphi XE8以来,您无法再取消选择Indy安装。任何构建自己的人都需要一个清理工具,以从Delphi自己的lib目录中删除内置的Indy。)

    • 另一个非常棒的技巧是在虚拟机上运行商业组件的安装程序,然后只需收集Pascal源代码并将其传输到您的干净开发机器上,然后自行构建。这样,您就可以避免当您的系统散布着BPL等文件甚至安装到C:\Windows\System32(在32位系统上)和C:\Windows\SysWow64(在64位系统上的相应路径)时所出现的可怕情况。


我安装了许多组件,没有任何问题,但当我安装DevArt SDAC时,在我退出Delphi之前它是成功的。每次我退出并重新运行Delphi时,都会显示“程序无法启动,因为您的计算机缺少dac105.bpl。请尝试重新安装...”我找不到解决方法 :( - QMaster
你的路径可能是错误的,缺少包含dac105.bpl的目录,或者包含dac105.bpl加载时加载的其他dll的目录。 - Warren P
谢谢@Warren。我找到了。我可能忘记安装一些.bpl文件。无论如何,我按照第二种方法将组件安装到IDE中(在SDAC安装程序的最后一页提到),现在它完美地工作了。第二种方法的简短部分是:“在'make.bat'中查找包含set IdeDir="D:\Program Files\Borland\Delphi"的行,并确保设置了正确的IDE路径并运行'Make.bat'...." - QMaster
我的路径和文件都在,但我仍然无法加载BPL,有什么建议吗? - AsepRoro
评论不是你在 Stack Overflow 上提问的地方。 - Warren P

3

将BPL文件(tee7100.bpl)放置在$(BDSCOMMONDIR)\Bpl目录下。

for XE: $(BDSCOMMONDIR)=  "C:\Users\Public\Documents\RAD Studio\8.0"
for XE5: $(BDSCOMMONDIR)=  "C:\Users\Public\Documents\RAD Studio\12.0"

这对我的情况没有帮助,但可能会帮助其他通过谷歌搜索的人。为了试图提供帮助而加一分! - Warren P

1
另一个可能导致此问题的原因是您存储.bpl文件的文件夹不在系统路径中。
这是因为Delphi尝试使用文件名而不是绝对路径调用WinAPI函数LoadLibrary。因此,如果Windows找不到文件,则Delphi无法加载它。
有关更多信息,请参见此论坛帖子
这似乎是Windows 7中的问题,但不是Windows 10中的问题。

1
对于更简单的情况,例如“我的BPL无法加载”(但我关于失败的传递依赖图的问题的其他部分),这当然是最简单的答案。在我们知道路径不是原因的情况下,由于路径或内部单元接口版本不匹配导致的传递依赖图失败是第二个原因。 - Warren P
@WarrenP 当然。我只是添加了这个问题,因为你是唯一一个提到bpl文件无法加载的人,而这正是我的情况的解决方案。 - Morgan Thrapp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接