如何部署ONLY.EXE和自定义.BPL文件



我想用插件开发GUI应用程序。插件包含从插件核心库中的基本表单继承而来的VCL表单。主应用程序可以选择动态加载哪个插件,然后选择显示哪个Form子类。

在用户端,我想部署main.EXE、插件核心库和许多用于不同型号的插件库。我可以向用户发布新的或修改现有的插件库,以显示新设备的新表单,而无需修改主.EXE和插件核心库。

我开发的第一个版本使用DLL方法,即插件核心库和插件都是DLL形式。用户方面一切都很好。然而,在开发人员方面,如果没有在插件核心DLL项目中定义的基本窗体,则无法链接插件DLL项目。这意味着基本表单实际上在每个插件DLL项目中都是静态链接的,如果有一天我修改基本表单并重建插件核心DLL项目,我必须重建所有插件DLL项目,并向用户重新发布插件.DLL

在StackOverflow中搜索和询问后,我意识到VCL窗体不能跨DLL边界继承的限制是由于RTTI冲突(?)。建议的解决方案是将库从DLL修改为BPL形式,这是我开发的第二个版本。除了以下两项之外,一切都很好:

  1. 从插件BPL动态加载的Form与Windows任务栏中的主.EXE分离。这不是我想要的。解决方案是,我在.EXE项目中启用了"使用运行时包构建"。

  2. .EXE项目中启用"使用运行时包构建"后,我必须向用户发布其他.bpl,如vcl.bpl>rtl.bpl[/strong>。这不是我想要的。

我想知道,以上两个问题可以同时解决吗?在我看来,如果我:,我可以解决这两个问题

  1. 禁用.EXE项目中的"使用运行时包构建"
  2. 在所有.BPL项目中启用"使用运行时包构建"

通过这种方式,.EXE可以在没有vcl.bpl>rtl.bpl捆绑的情况下运行,并且插件.bpls可以成功加载,因为依赖单元已经是主>.EXE的一部分了?我说得对吗?但是,在所有.BPL项目选项中,"使用运行时包构建"复选框都被禁用。因此,我没有机会检查解决方案是否有效。很抱歉描述太长,由于公司的网络安全政策,我无法附上图片。

从插件BPL动态加载的Form与Windows任务栏中的主.EXE分离。这不是我想要的。解决方案是,我在.EXE项目中启用了"使用运行时包构建"。

加载BPL后,将EXE的Application.Handle传递给BPL,并在创建任何Form实例之前将其分配给BPL自己的Application.Handle

或者,在Windows 7+上,您可以让EXE调用SetCurrentProcessExplicitAppUserModelID()为其任务栏按钮建立应用程序ID。然后,BPL中的每个Form都可以使用SHGetPropertyStoreForWindow()IPropertyStore.SetValue(PKEY_AppUserModel_ID)为其窗口设置相同的应用程序ID。具有相同应用程序ID的多个窗口组合在一个任务栏按钮下。

有关更多详细信息,请参阅MSDN:应用程序用户模型ID(AppUserModelID)

我想知道,以上两个问题可以同时解决吗?在我看来,如果我:,我可以解决这两个问题

  1. 禁用.EXE项目中的"使用运行时包生成"。

  2. 在所有.BPL项目中启用"使用运行时包构建"。

通过这种方式,.EXE可以在没有vcl.bpl和rtl.bpl捆绑的情况下运行,并且插件.bpl可以成功加载,因为依赖单元已经是主.EXE?我说得对吗?

没有。BPL不能像那样使用EXE的内置单元。

如果禁用"使用运行时包构建",RTL/VCL单元将静态链接到可执行文件中。这样做的问题是,给定单元的多个副本无法同时加载到内存中,因此,如果相同的RTL/VCL单元静态链接到多个BPL,甚至EXE本身,则无法将多个BPLs一起加载(甚至根本无法加载)。

如果启用"使用运行时包构建",则可执行文件将依赖于RTL/VCL BPL,然后必须部署这些BPL。

因此,如果EXE和BPL共享公共单元,则这些单元必须通过共享BPL加载,因此内存中只存在一个单元副本。在编写自定义BPL时,无法避免这种情况。这意味着,如果您使用基本的RTL功能,则至少您通常必须部署RTL.BPL,而UI则必须部署VCL.BPL。

相关内容

  • 没有找到相关文章

最新更新