Tuesday, June 24, 2008

TypeLib or not TypeLib

That is the question.
Whether tis nobler in the mind to suffer
the slings and arrows of outrageous fortune,
or just use the bloody Registry table?


It seems that Microsoft have effectively deprecated the TypeLib table.

From the msdn docs:

Installation package authors are strongly advised against using the TypeLib table. Instead, they should register type libraries by using the Registry table. Reasons for avoiding self registration include:

  • If an installation using the TypeLib table fails and must be rolled back, the rollback may not restore the computer to the same state that existed prior to the rollback. Type libraries registered prior to rollback may not be registered after rollback.
Additionally, if you compare (using InstEd of course) the _BadRegData tables from early darice.cub files with that in the latest Windows Server 2008 SDK, all the references to TypeLib subkeys have been removed. This means they no longer show up as ICE33 errors. Microsoft really want you to put TypeLib registration into the Registry table.

But why is this? Their justification is that registry keys created/overwritten by the RegisterTypeLibraries action cannot be restored to their previous state upon rollback. With the Registry table entries, the Windows Installer engine guarantees that registry keys modified during an installation are returned to their previous state upon rollback.

However the RegisterTypeLibraries action most likely calls the RegisterTypeLib api. The Windows Installer engine has no control over what that api does, and cannot therefore manage the registry keys so that they are restored upon rollback.

Hence Microsoft's strong suggestion to use the Registry table.

But a closer examination shows that the suggestion solves a problem only when things go wrong, and leave a gaping problem when things go right.

Consider the automobile airbag. It's a fantastic device for saving the average driver's face of average attractiveness in the case of an accident. We are all grateful they exist. The Registry table is the Windows Installer airbag. It saves the registry from deformity in the case of an accident by ensuring that, upon rollback, the registry is restored to its state prior to the installation.

However, imagine that whenever the driver turned the ignition off, the steering wheel whacked them in the face, airbag safely tucked inside it's protective casing.

This is the problem with declaring the typelib table unsafe. Sure, the airbag will save you when you have an accident, something most drivers don't set out to do. But the Windows Installer engine can't save the registry when everything goes well, the package is installed perfectly, and then is uninstalled for whatever reason, regardless of whether registry keys are set via the Registry or the TypeLib tables.

The Windows Installer engine only holds the registry state for the duration of the installation, allowing restoration only upon rollback. Upon successful installation and uninstallation, both the Registry table and the TypeLib table will result in keys/values being deleted, regardless of their state prior to the installation. It's the whack in the face for turning the ignition off.

Addressing the airbag issue, it seems that given they have the code for the RegisterTypeLib api (and code for rollback of the registry), they could supplant it with one that successfully restores the registry table upon rollback, just like the Registry table does. This would provide all the same protection as the Registry table, and not require modification of all the existing msi's out there.

So, should you use the TypeLib table? Well, given that MS haven't done the work to allow successful rollback on the TypeLib table, if you have the tools to automatically generate the Registry table entries, then I can't see why not. But the extra work may not be worth it, considering that the majority of cases where things go as intended (install/unsintall) will suffer the same problems as the minority of cases when things have gone wrong (rollback).

The only caveat to this is that most conflict checking utilities will not look inside a typelib for conflicts between typelibs (e.g. this interface's typelib info is provided by this file, no this file, no this file). In this case, using the Registry table probably provides a more significant benefit than using the TypeLib table (note to software vendors, your packages will likely be used in enterprises where they are conflict managed, so help them out).

But this of course isn't Microsoft's justification, and their justification seems a little weak for such a strong recommendation.

1 comment:

Greg Lambert said...

Excellent post... been struggling with the Typelib stuff for a while...

And.. nice editing tool as well... wish we had a snap-shot feature as well...