简体   繁体   English

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

[英]How to deploy ONLY .EXE and custom .BPL files?

I would like to develop GUI application with plugins.我想用插件开发 GUI 应用程序。 The plugins contains VCL Forms which are inherited from Base Forms in the Plugin-Core library.插件包含从 Plugin-Core 库中的 Base Forms 继承的 VCL Forms。 The main application can select which plugin to load dynamically, and then which Form subclasses to display.主应用可以选择动态加载哪个插件,然后显示哪个Form子类。

In the users side, I would like to deploy main .EXE , the Plugin-Core library, and many plugin libraries for different models.在用户端,我想部署主.EXE 、插件核心库和许多不同模型的插件库。 I could release new or modify existed plugin libraries to users to display new Forms for new devices without modifying the main .EXE and the Plugin-Core library.我可以向用户发布新的或修改现有的插件库以显示新设备的新表单,而无需修改主.EXE和插件核心库。

The first version I developed uses DLL approach, namely both the Plugin-Core library and the plugins are in DLL form.我开发的第一个版本使用 DLL 方法,即 Plugin-Core 库和插件都是 DLL 形式。 Everything is just fine on the users side.在用户方面一切都很好。 However, in the developers side, the plugin DLL project can not be linked without Base Forms defined in the Plugin-Core DLL project.但是,在开发者方面,如果没有在 Plugin-Core DLL 项目中定义的 Base Forms,则无法链接插件 DLL 项目。 It means that the Base Forms are actually statically linked in each plugin DLL project, and if someday I modify the Base Forms and rebuild the Plugin-Core DLL project, I have to rebuild all plugin DLL projects and re-release plugin .DLL s to users, too.这意味着 Base Forms 实际上是静态链接在每个插件 DLL 项目中的,如果有一天我修改 Base Forms 并重建 Plugin-Core DLL 项目,我必须重建所有插件 DLL 项目并将插件.DLL重新发布到用户也是。

After searching and asking in StackOverflow, I realized the limitation that VCL Forms can NOT be inherited across DLL boundary is due to RTTI conflict(?).在 StackOverflow 中搜索和询问后,我意识到 VCL Forms 不能跨 DLL 边界继承的限制是由于 RTTI 冲突(?)。 The suggested solution is to modify the libraries from DLL to BPL form, which is the second version I developed.建议的解决方案是将库从 DLL 修改为 BPL 形式,这是我开发的第二个版本。 Everything is also fine except the following two:除了以下两个之外,一切都很好:

  1. The dynamic loaded Form from plugin BPL is separated from the main .EXE in Windows taskbar.从插件 BPL 动态加载的 Form 与 Windows 任务栏中的主.EXE分开。 It is not what I desired.这不是我想要的。 The solution is that I enabled "Build with runtime packages" in the .EXE project.解决方案是我在.EXE项目中启用了“使用运行时包构建”。

  2. After I enabled "Build with runtime packages" in the .EXE project, I have to release other .BPLs to the users, such as vcl.bpl and rtl.bpl ..EXE项目中启用“使用运行时包构建”后,我必须向用户发布其他 .BPL,例如vcl.bplrtl.bpl This is not perfectly what I desired.这不是我想要的。

I would like to know that the above two issues can be resolved at the same time?请问以上两个问题可以同时解决吗? In my thought, I could resolve both two issues if I:在我看来,如果我能解决这两个问题:

  1. Disable "Build with runtime packages" in .EXE project..EXE项目中禁用“使用运行时包构建”。
  2. Enable "Build with runtime packages" in all .BPL projects.在所有.BPL项目中启用“使用运行时包构建”。

In this way, the .EXE can run without vcl.bpl and rtl.bpl bundled, and the plugin .BPL s can be loaded successfully because the dependent units are already part of the main .EXE ?这样, .EXE可以在没有vcl.bplrtl.bpl捆绑的情况下运行,并且插件.BPL可以成功加载,因为依赖单元已经是主.EXE 的一部分? Am I correct?我对么? However, the "Build with runtime packages" checkbox is disabled in all .BPL project options.但是,所有.BPL项目选项中都禁用了“使用运行时包构建”复选框。 As a result I don't have a chance to check whether the solution works or not.因此,我没有机会检查解决方案是否有效。 I am sorry for the lengthy description and I can not attach picture due to company's Internet security policy.对于冗长的描述,我很抱歉,由于公司的互联网安全政策,我无法附上图片。

The dynamic loaded Form from plugin BPL is separated from the main .EXE in Windows taskbar.从插件 BPL 动态加载的 Form 与 Windows 任务栏中的主 .EXE 分开。 It is not what I desired.这不是我想要的。 The solution is that I enabled "Build with runtime packages" in the .EXE project.解决方案是我在 .EXE 项目中启用了“使用运行时包构建”。

After loading a BPL, pass the EXE's Application.Handle to the BPL and assign it to the BPL's own Application.Handle before it creates any Form instances.加载 BPL 后,将 EXE 的Application.Handle传递给 BPL 并将其分配给 BPL 自己的Application.Handle然后再创建任何 Form 实例。

Alternatively, on Windows 7+, you can have the EXE call SetCurrentProcessExplicitAppUserModelID() to establish a App ID for its taskbar button.或者,在 Windows 7+ 上,您可以让 EXE 调用SetCurrentProcessExplicitAppUserModelID()为其任务栏按钮建立应用 ID。 Then each Form in the BPLs can use SHGetPropertyStoreForWindow() and IPropertyStore.SetValue(PKEY_AppUserModel_ID) to set the same App ID for their windows.然后 BPL 中的每个 Form 都可以使用SHGetPropertyStoreForWindow()IPropertyStore.SetValue(PKEY_AppUserModel_ID)为其窗口设置相同的 App ID。 Multiple windows with the same App ID are grouped together under a single taskbar button.具有相同 App ID 的多个窗口组合在一个任务栏按钮下。

See MSDN for more details: Application User Model IDs (AppUserModelIDs)有关更多详细信息,请参阅 MSDN: 应用程序用户模型 ID (AppUserModelIDs)

I would like to know that the above two issues can be resolved at the same time?请问以上两个问题可以同时解决吗? In my thought, I could resolve both two issues if I:在我看来,如果我能解决这两个问题:

  1. Disable "Build with runtime packages" in .EXE project.在 .EXE 项目中禁用“使用运行时包构建”。

  2. Enable "Build with runtime packages" in all .BPL projects.在所有 .BPL 项目中启用“使用运行时包构建”。

In this way, the .EXE can run without vcl.bpl and rtl.bpl bundled, and the plugin .BPL s can be loaded successfully because the dependent units are already part of the main .EXE?这样,.EXE 可以在没有 vcl.bpl 和 rtl.bpl 捆绑的情况下运行,并且插件 .BPL 可以成功加载,因为依赖单元已经是主 .EXE 的一部分? Am I correct?我对么?

No. BPLs cannot use the EXE's built-in units like that.不可以。BPL 不能像那样使用 EXE 的内置单元。

If you disable "Build with Runtime Packages", the RTL/VCL units will be statically linked into the executable file.如果禁用“Build with Runtime Packages”,RTL/VCL 单元将静态链接到可执行文件中。 The problem with doing that is multiple copies of a given unit cannot be loaded in memory at the same time, so you wouldn't be able to load multiple BPLs together (or even at all) if the same RTL/VCL units are statically linked into multiple BPLs, or even the EXE itself.这样做的问题是给定单元的多个副本不能同时加载到内存中,因此如果相同的 RTL/VCL 单元静态链接,您将无法一起加载多个 BPL(甚至根本无法加载)成多个 BPL,甚至是 EXE 本身。

If you enable "Build with Runtime Packages", the executable file will be dependent on the RTL/VCL BPLs, which must then be deployed.如果启用“使用运行时包构建”,则可执行文件将依赖于 RTL/VCL BPL,然后必须部署这些 BPL。

So, if your EXE and BPLs share common units, those units must be loaded via shared BPL(s) so only one copy of the units exist in memory.因此,如果您的 EXE 和 BPL 共享公共单元,则这些单元必须通过共享 BPL 加载,因此内存中仅存在单元的一个副本。 There is no avoiding that when writing custom BPLs.在编写自定义 BPL 时无法避免这一点。 Which means at a minimum you usually have to deploy RTL.BPL if you are using basic RTL functionalities, and VCL.BPL for UIs.这意味着如果您使用基本的 RTL 功能,通常至少需要部署 RTL.BPL,以及用于 UI 的 VCL.BPL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM