5

我们使用微软的 ActiveX/COM (VB6) 技术开发了一个软件系统。去年,我对自动化构建过程和整个 SCM 越来越感兴趣。我在网上大量搜索了有关如何使用基于 COM 的软件系统进行 scm 的最佳实践的信息。

COM 的“问题”是,引用组件通过唯一的接口 id 保存引用。当您重新编译引用的组件时,id 可能会更改并且引用不再有效。这里的主要问题是,iid 被编译成二进制文件。因此,当我不想将编译后的文件签入版本控制时,每个开发人员都必须编译他/她自己的版本并获取其他 id。

当我想在干净的构建机器上检查源代码来编译系统时,这是不可能的,因为所有的引用都是无效的(没有二进制文件,没有接口 id)。

我只是想知道,如果有一些最佳实践,如何为 COM 项目(VB6)设置自动构建系统?

编辑: 是的,我知道兼容性设置。但是以这种情况为例,我想在没有任何二进制文件的干净构建机器上构建 wohle 系统。当您说项目兼容二进制时,您必须提供与该项目兼容的二进制文件。

我想我必须编写一个自定义构建工具,它在编译项目之前和之后修改项目文件中的引用和兼容性设置。

因为 VB6 / COM 是一种非常广泛的技术,我只是想必须有一个现成的解决方案。

我们通常使用二进制兼容性进行编译。当我们修改一个组件的公共接口时,我们以项目兼容性进行编译。但是当你改变一个被许多其他组件使用的基本组件的接口时,你必须手动将所有引用项目更改为项目兼容性,重新编译它们并改回二进制兼容性。这就是我想要自动化的主要过程。

4

3 回答 3

11

您可以通过将项目的兼容性设置从“无兼容性”更改为“二进制兼容性”来告诉 VB6 重用 GUID(IID 的 CLSID 的 LIBID 等)。您可以在 Project-> Your-Project Properties 下找到这些设置。兼容性设置位于“项目属性”窗口的“组件”选项卡上。有三种选择:

  • 不兼容
  • 项目兼容性
  • 二进制兼容性

以下是MSDN对它们的评价:

不兼容


使用此设置,不强制执行兼容性。每次生成或编译项目时,Visual Basic 都会创建新的接口 ID 和类 ID。构建的每个版本只能用于为使用该组件的特定构建而创建的应用程序。

项目兼容性


使用此设置,您可以使您的项目与特定组件项目兼容。在生成新的类型库信息时,会维护类型库标识符,以便测试项目仍然可以引用组件项目。此设置用于在测试期间保持兼容性。因此,一旦组件被释放,它的行为就与“无兼容性”设置相同。

二进制兼容性


编译项目时,Visual Basic 仅在必要时创建新的类和接口 ID。它保留了以前版本的类和接口 ID,以便使用早期版本编译的程序将继续工作。如果您所做的更改会导致版本不兼容,Visual Basic 会警告您。如果您想保持与旧版本的 ActiveX 组件的兼容性,这是您需要使用的设置。

听起来您当前正在使用No Compatibility进行编译。正如 MSDN 文章所述,您需要使用二进制兼容性来保持组件的新版本与旧版本兼容。您现在可以通过执行以下操作来做到这一点:

  • 每个项目编译一次,不兼容

  • 将这些“干净”版本保存到构建人员可以轻松访问的文件夹中,例如网络共享,或者将它们置于源代码控制中。

  • 返回并将所有项目更改为“二进制兼容性”并将“兼容文件”指向您刚刚保存在网络/源代码管理中的相应版本(不要将兼容文件指向您正在编译的相同路径项目到。兼容文件应该是原始组件的单独副本,不会更改。它的存在只是为了让 VB 可以在重新编译时将该文件中的 ID 复制到您的项目中)。

每次重新编译项目时,它们都会重用组件的兼容(原始)版本中的 GUID。

编辑:正如 Joe 在评论中提到的,您还必须认识到您的类接口何时发生了变化(即,当接口发生足够的变化时,您可以再保持与以前版本的二进制兼容性)。发生这种情况时,您希望彻底摆脱以前版本的组件:重新编译一个新的“干净”版本(即不兼容)并在将来的构建中使用该新版本作为兼容文件。但是,重要的是要注意只有在类接口(属性和方法)发生更改时才应该重新开始。事实上,当项目不再与以前版本的组件兼容时,VB 会警告您。

如果你想生活在边缘...


在我工作的地方,我们倾向于(ab)在我们的大多数项目中使用 No Compatibility,即使它不是真正正确的做事方式(你应该使用 Binary Compatibility)。在我们公司,这是一种懒惰,因为我们有一个自动构建工具,可以为我们编译所有项目,该工具的主要功能之一是可以自动修复项目之间损坏的项目引用。由于构建工具为我们解决了这个问题,因此使用二进制兼容性的动机较少。

为什么二进制兼容性更好(或者......为什么你不应该做我们所做的)


二进制兼容性通常是更好选择的几个原因:

  • 微软这么说

  • 如果您的所有组件都与软件的先前版本二进制兼容,那么您可以轻松地重新编译单个组件并将其重新分发给您的客户。这使得错误修复/补丁更易于部署。如果您在项目中使用 No Compatibility,则每次需要发布一个小补丁时,您都必须重新编译和重新分发整个应用程序,因为较新的组件(可能)无法与较旧的组件一起使用。

  • 您正在尽自己的一份力量维护 COM 标准:在 COM 中,类 ID 和接口 ID 应该唯一标识一个类或接口。如果您的类和/或接口在构建之间没有改变,那么就没有理由为这些类和接口生成新的 ID(事实上,同一个类会有多个 ID)。二进制兼容性允许您跨构建维护相同的 ID,这意味着您是一个好公民并遵循 COM 约定。

  • 减少注册表噪音。如果您总是向与旧版本二进制不兼容的客户部署新组件,则每个新版本都会向注册表添加新信息。除其他事项外,每个新接口和类 ID 都必须注册。如果您保持所有二进制兼容,那么安装程序只需将注册表项添加到一个位置,因为您的类 ID 和接口 ID 不会更改。

  • 如果您要公开其他第三方应用程序正在使用的公共 API 或组件,您肯定会希望使用二进制兼容性,这样您就不会破坏依赖于您的代码的第三方软件。

于 2008-10-07T18:01:52.293 回答
5

视觉生成专业版。如果您仍然停留在 VB6 领域,并且必须构建专业产品,我强烈建议您研究这个产品。它提供免费试用,每一分钱都物有所值(此外,它在 .Net 和其他平台的持续集成方面做得非常好。)自从我们开始使用它以来,它在每次发布时都将我们从 DLL 地狱中拯救了出来。我知道没有其他方法可以在 VB6 中创建一个像样的构建框。

于 2008-10-08T16:33:01.830 回答
4

正如 Mike Spros 所建议的,您应该使用 Binary Compatibility。您可以(并且应该)在干净的机器上构建。为此,您可以在源代码控制系统的“兼容”目录中保留一份当前生产二进制文件(ActiveX DLL 和 OCX)。当您选择二进制兼容性时,所有项目都应参考此副本。例如,将新的二进制文件放到 ...\Release 中,兼容的二进制文件放在 ...\Compatible 中。当新版本投入生产时,您将所有内容从 ...\Release 复制到 ...\Compatible。通过这种方式,您可以保持从一个版本到下一个版本的兼容性。

在二进制兼容模式下,如果您向类中添加新方法,VB 将创建一个新的 IID。请记住,在 COM 中,接口是不可变的。如果您对界面进行最轻微的更改,那么您就是在创造新的东西。VB 遵守 COM 的这条规则,但使用一些烟雾和镜子来防止破坏旧的客户端代码。因为 VB “知道”新接口是旧接口的 100% 超集(这是二进制兼容性所确保的),所以它可以使用“接口转发”。接口转发只是将所有引用从旧接口重定向到新接口。如果没有这个技巧,您将不得不为您修改的任何 ActiveX 组件创建新版本(具有不同的名称和 CLSID)。DLL Hell 将变成 DLL Armargeddon!

VB 将所有接口转发信息存储在组件的资源中。当您注册组件时,它会将所有接口 IID 写入 HKCR\Interface。较旧的接口将在其中包含转发信息。只有“真正的”接口才会引用实际的 coclass。

于 2008-12-17T06:46:49.367 回答