Buildprocess for corporate projects ActiveX / COM / VB6

We have developed a software system using Microsoft ActiveX / COM (VB6) technology. Last year, I became more and more interested in automatic assembly processes and SCM in general. I intensively searched large parts of the Internet for information on best practices for working with scm with COM-based software systems.

The “problem” with COM is that the referenced component contains the link using a unique interface identifier. When you recompile the referenced component, the identifier may change, and the link is no longer valid. The main problem here is that iid is compiled to binary. Therefore, when I do not want to check the compiled files in version control, each developer must compile their own versions and get other identifiers.

When I want to check the source on a clean build machine to compile the system, it is simply impossible, because all the links are invalid (no binaries, no interface identifiers).

I'm just wondering if there are any best practices for setting up an automatic build system for COM projects (VB6)?

Edit: Yes, they know about compatibility settings. But take a scenario where I want to build a wohle system on a clean build machine without any binaries. When you say that the project is binary compatible, you must provide a binary compatible with the project.

I think that I need to write a special build tool that changes the links and compatibility parameters in the project files before and after compiling the projects.

Since VB6 / COM is a really widespread technology, I just thought there should be a ready-to-use solution.

Usually we compile with binary compatibility. When we modify the open interface of a component, we compile it with the compatibility of the project. But when you change the interface of the base component, which is used by many other components, you must manually change the entire project of the project compatibility links, recompile them and return to binary compatibility. This is the main process that I want to automate.

+4
source share
3 answers

Visual Build Pro . If you are still stuck on VB6 and need to create professional products, I highly recommend that you study this product. It has a free trial and is worth every penny (plus it does a pretty good job of continuous integration for .Net and other platforms.) It has saved us from the DLL addon in every release since we started using it. I don’t know of another way to create a decent build block in VB6.

+5
source

You can tell VB6 to reuse the GUID (IID CLSID LIBID, etc.) by changing the project compatibility setting to "No Compatibility" to "Binary Compatibility". These options can be found in the section "Project-> Your-Project Properties". The compatibility setting is located on the Component tab of the Project Properties window. There are three options:

  • No compatibility
  • Project compatibility
  • Binary compatibility

Here MSDN talks about them:

No compatibility


There is no compatibility with this setting. Visual Basic creates new interface identifiers and class identifiers each time you create or compile your project. Each version can only be used with applications created to work with this specific component layout.

Project compatibility


With this setting you can make your project compatible with a specific component project. While the new type is library information, the type library identifier so that test projects can still reference the project component. This option is to maintain compatibility during testing. Therefore, as soon as a component is freed, it behaves in the same way as the “No compatibility” parameter.

Binary compatibility


When you compile your project, Visual Basic only creates new classes and Interface Identifiers if necessary. This saves class and interface identifiers from the previous version (s) so that programs compiled using the earlier version will continue to work. if you make changes that result in an incompatible version, Visual Basic will warn you. If you want to maintain compatibility with older, released versions of the ActiveX component, this is the setting you need to use.

It looks like you are currently compiling No compatibility . As stated in the MSDN article, you need to use Binary Compatibility to keep older versions of your components compatible with older versions. You can do it now by following these steps:

  • Compile each project once with No Compatibility

  • Save these “clean” versions to a folder that assembly users can easily access, such as a network share, or put them in the source code.

  • Go back and change all projects to “Binary Compatibility” and point “Compatible File” to the corresponding version that you just saved on the network / in the original control (do not point the compatible file to the path to which you are compiling the project. Compatible the file must be a separate copy of the source component, which will not change. It exists only so that VB can copy the identifier from this file to your project when it is recompiled).

Each time you recompile your projects, they will reuse the GUID from compatible (original) versions of the components.

EDIT: As Joe pointed out in the comments, you also need to find out when the interfaces of your class have changed (that is, when the interface has changed so much that you can maintain compatibility with previous versions for longer). When this happens, you want to make a clean break with previous versions of the components: recompile the new “clean” version (ie No compatibility) and use this new version as a compatible file in future builds. However, it is important to note that you should start over when the interfaces of your class (properties and methods) change. In fact, VB will warn you when a project is no longer compatible with a previous version of a component.

If you want to live on the edge ...


Where I work, we tend to (ab) use No Compatibility for most of our projects, although this is not the right way to do something (you should use Binary Compatibility). Laziness was acquired in our company, because we have an automatic assembly tool that compiles all our projects for us, and one of the main features of this tool is that it can automatically restore broken links to projects between projects. Since the build tool fixes this for us, there are fewer incentives to use binary compatibility.

Why is binary compatibility better (or ... why you shouldn't do what we do)


A few reasons why binary compatibility is usually the best choice:

  • Microsoft says that

  • If all your components are compatible with previous versions of the software, you can easily recompile one component and redistribute it to your customers. This simplifies the deployment of patches / patches. If you use “No Compatibility” in your projects, you will have to recompile and redistribute your entire application each time a small patch is required, because newer components (probably) will not work with older components.

  • You do your part to support the COM standard: in COM, the class identifier and interface identifier must uniquely identify the class or interface. If your classes and / or interfaces have not changed between assemblies, then there is no reason to generate a new identifier for these classes and interfaces (in fact, the same class will have several identifiers). Binary Compatiblity allows you to maintain the same identifier in assemblies, which means that you are a good citizen and follow the COM conventions.

  • Less registry noise. If you always deploy new components for clients that are not compatible with older versions, each new version adds new information to the registry. Each new interface and class identifier must be registered, among other things. If you store all Binary Compatible, then the installer should only add registry keys in one place, since your class identifier and interface identifier will not change.

  • If you publish a public API or component that consumes other third-party applications, you will definitely want to use binary compatibility so as not to violate third-party software that depends on your code.

+10
source

As Mike Sprass suggests, you should use binary compatibility. You can (and should) build on a clean machine. You do this by storing a copy of the current executable files (ActiveX DLL and OCX) in a "compatible" directory in your version control system. All projects should reference this copy when you select Binary Comatibility. For example, add new binaries to ... \ Release and compatible executables to ... \ Compatible. When the new version goes into production, you copy everything from ... \ Release to ... \ Compatible. Thus, you maintain compatibility from one release to another.

When VB creates a new IID in binary compatibility mode, if you add a new method to your class. Remember that in COM, the interface is unchanged. If you make a small change to the interface, you are creating something new. VB abides by this COM rule, but uses smoke and mirrors to prevent breaking old client code. Since VB “knows” that the new interface is a 100% superset of the old interface (this is what provides binary compatibility), it can use “interface forwarding”. Forwarding an interface simply redirects all links from the old interface to the new interface. Without this trick, you will have to create new versions (with different names and CLSIDs) of any ActiveX component that you modify. DLL Hell will turn into DLL Armargeddon!

VB stores all information about interface forwarding in the resources of your component. When you register a component, it writes all the IIDs in the HKCR \ Interface. Older interfaces will have forwarding information in them. Only the "real" interface will refer to the actual class.

+4
source

Source: https://habr.com/ru/post/1277538/


All Articles