Join us for SoftSummit 2023. The 20th anniversary of the industry leading software monetization conference. April 18 and 20. Register Now

Showing results for 
Show  only  | Search instead for 
Did you mean: 
Level 4

ActiveX COM Registration on minor updates (msi project)

In a basic MSI project, during a minor upgrade, how can you unregister the previous ActiveX COM components (DLL/OCX/EXE) before installing the new one?

The major upgrade works fine but seems like overkill to update only a handful of files...

The minor upgrade results in duplicate registry entries for every ActiveX whose interface has changed; after that, uninstalling leaves orphaned registry entries.

Is it the norm to *always* do major upgrades if you have ActiveX components to update? (Seriously?)

Has anyone found a solution to this? :confused:
Labels (1)
0 Kudos
6 Replies
Level 12 Flexeran
Level 12 Flexeran

If you're getting extra registry keys, it sounds like you're renaming (thus removing and adding) the keys. This is a no-no per component rules, and in practice is especially bad in a minor upgrade. From the perspective of Windows Installer, you should not be making these kinds of changes in a minor version, if at all. In practice, there are probably workarounds for specific cases, at least if you are using static or manual COM extraction.

If you're worried specifically about the overkill, you could consider a different kind of overkill: separate your package into multiple packages. One package will include the items that are unlikely to change in such a breaking fashion. The other package or packages will include various items that are likely to be updated in this fashion. Then you can fully update the smaller packages without having to uninstall or reinstall the non-changing items. However this sort of packaging change is no small task, even with Suite projects (assuming you have the Premier edition so you can use them), so that's why I call it another kind of overkill.
0 Kudos
Level 4

So, to clarify:

Say I have an ActiveX DLL, with one function, say Function DoThis(); once compiled I get a v1.0 typelib version.
This DLL is delivered in a v1.0.0 MSI package, with the rest of the application.

Adding a Function DoThat() to that ActiveX DLL will bump its typelib to v1.1, and changes its COM registration accordingly.
This DLL is delivered in v1.1.0 MSI package, with the rest of the application. Let's say only this DLL has changed.

Note that any exe or library compiled to use the typelib v1.0 remains compatible with the v1.1 typelib.

By my understanding of your explanation and the component rules, since the typelib registration has changed, going from the MSI v1.0.0 to v1.1.0 could only be done by a major upgrade, right?

If this is indeed the situation, it's means minor updates can never be used in any scenario where ActiveX components need to be updated, right?

Is the industry norm for updating applications with many ActiveX COM components (exe/dll/ocx) to always do major updates?
If not, what?

Any feedback or insight into this issue greatly appreciated.
0 Kudos
Level 12 Flexeran
Level 12 Flexeran

Let's take it down to actual registry keys.

Let's say that upgrading from v1 to v2 of your MSI makes the following change:
[CODE][HKLM\Software\Classes\CLSID\{Guid}] -> [HKLM\Software\Classes\CLSID\{Guid}]
@="Name v1" @="Name v2"[/CODE]
Then a minor upgrade can handle this fine. Why? Because it's a change to a value data, not a new key, or a new value name.

If, however, the change looks like this:
[CODE][HKLM\Software\Classes\TypeLib\{Guid}\1.0] -> [HKLM\Software\Classes\TypeLib\{Guid}\2.0]
@="Name v1" @="Name v2"[/CODE]
Then you may have a problem. Why? Because the obvious representation of this deletes and adds at least one registry key. If you just change the values in the component, install the minor upgrade, and then remove the minor upgrade, the 1.0 key is left behind as there is no longer any record of it.

How are you supposed to handle this? There are two main approaches. One is to break component rules anyway and change it via a major upgrade. This works well enough for components that are not shared among multiple installations, and thus will only ever exist in one configuration at a time on a target machine. The other is to figure out what you have to do to follow component rules. If you are changing the path of the file that this references, then update the component code (that is, create a new component), and you can avoid a component rules violation. To distribute that successfully as a minor upgrade, you will also have to maintain the old component's data and either let it stay installed, or use the component setting "Reevaluate Condition" with a false Condition to get it removed.

The thing to remember is that Windows Installer isn't looking at this as a question of what sort of changes did you make to your type library. It's only looking at the data it's been told, and it requires that data to follow certain rules in order for scenarios like a minor upgrade to work fully.
0 Kudos
Level 4

Thanks for the clarifications Michael.

I finally got a proof of concept set of msi packages to do a minor upgrade from v1.0.0 to v1.1.0 successfully, with no leftover residual registration info from the old ActiveX component, by using this method when building the msi package v1.1.0:

  • On the msi component for the old ActiveX, set the Condition to '0' (false) to force a removal (I also set Reevaluate Condition to Yes - not sure if necessary)
  • Add the updated ActiveX as a new msi component, thus creating a new component code for the updated ActiveX DLL/OCX/EXE (GUID)
    *Note: the updated ActiveX replaces the old one, in the same path when installed.
  • Keep the Product Code and Upgrade Code unchanged from msi package "v1.0.0" to "v1.1.0"; new Package Code always generated on build as per default IS settings

    Granted, this method works, but it makes it impossible to use a "static" basic msi project for automated builds and requires manually editing the package definition for every build. I'm guessing using "extract COM at build" is not possible either.
    It also means keeping ALL previous versions of all ActiveX DLL/OCX/EXE in the latest msi package, since the last major upgrade.

    Even though my proof of concept msi package had only one ActiveX DLL to update, arranging the msi for a successful minor update proved tedious and very hands on; doing this for 20+ components every time we need to build a package will be a major setback vs. our current automated build process...

    Surely we are not the first to hit this problem. How do others deal with the ActiveX registration/minor upgrade issue?
  • 0 Kudos
    Level 4

    Seriously though, how do people typically go about updating their ActiveX components?
    Are they always doing major updates?

    ActiveX COM may not the favored tech today, but it's still going to be around for some while, and the Windows Installer service has also been around for a while now: how is it that Microsoft or InstallShield hasn't made it easier to do something as simple as updating an ActiveX DLL?

    It baffles the mind. :confused:
    0 Kudos
    Level 4

    Also note:
    When rebuilding the msi package with updated ActiveX files using the same msi component codes, same basic msi project def., if we specify the previous msi package as a reference for a MinorUpgrade item, the IS2014 IDE *does* warn about registry entries that will be orphaned, as shown below :

    ISDEV : warning Val0009: A registry entry has been removed from the component 'AlphaBravoCharlie.dll.v1.0'. This key must be added to the RemoveRegistry table, otherwise it will be orphaned by an upgrade. '0|interface\{64973099-33b4-4701-b72f-64ce94df2604}\typelib|'. c:\abctest\sources.v1.1\kit.previous\abcinstallermsi.msi

    Since the build engine is aware of the specific registry keys that will be orphaned, having a provision to automatically add these keys in the RemoveRegistry table would have been the definitive solution to the problem...

    Could InstallShield not implement this?
    0 Kudos