.net – Replicating Visual Studio COM registration with a WiX Installer

comnettypelibwindowswix

Once upon a time, a young, naive engineer thought it would be a good idea to separate out some of the functionality for his app into a COM component, written in C#. Visual studio had all the tools to do that, right? .NET was practically made for this, right? HA! He said, this will be easy. I'll have decent separation of components, keeping business logic away from the front end, and with COM, I'll be able to use it from anywhere! He merrily checked the register for COM interop checkbox in the project properties, exposed the classses he wanted, and went on his way.

Oh, the trials such a choice made. The young engineer now, more experienced, would not now wish this upon anyone. However, the burden had been placed upon his shoulders, and the burden remained heavy. He looked to lighten the load.

Along came WiX, a tool for generating Windows Installer files from XML. This intrigued him – it could replicate, quite simply, most of the code needed for a proper windows installer file simply from a handful of configuration files. His sights were looking up.

With WiX 2.0, he could generate quite easily the files needed to register a C# COM object. This involved using the tool tallow. He'd do something like the following:

tallow -c -nologo MyComExposedLibrary.dll > MyComExposedLibrary.wxs

which would then be fixed up (at first this was done manually, but eventually I recorded the steps into a small tool set the final directory ref id, component ID, fileID, GUID and codebase).

Then, the ensuing installer would install, and there would be joyous celebration, if the app worked.

Which it did not.

For days the young engineer poured over the differences on his development PC and that of the test install PC. "All the registry keys are the same!" He would exclaim. "Everything for MyComExposedLibrary is registerd, I swear!"

Except, it wasn't.

On the dawn of third day, after many a mountain dew, he realized there was one more object that Visual Studio was registering that his installer was not: the MyComExposedLibrary.tlb file.

Visual Studio, apparently, had been registering this file all along, creating additional subkeys in the HKLM\Software\Classes\Interface registry key, and registering the typelib in HKLM\SOFTWARE\Classes\TypeLib.

Tallow gave no help, complaining that a .tlb wasn't a file it groked. Nor the WiX 3.0 beta – this seemed to have even more issues getting things working.

I also gave Heat a try. This generated registry elements and class elements. I cleaned up heat's output, and then went to compile it, but got a different error: error LGHT0130 : The primary key <uuid here> is duplicated in table 'Registry'. Problem is, as far as I can tell, that uuid doesn't actually exist in any of my wxs source files. If I change around the component ref order in my feature element, a different dll component gives that error. Since I have been unsuccessful at getting a WiX 3.0 version of the project to compile, I haven't been able to confirm whether or not heat gives the right output.

I removed everything from the installer except for one of the assembly that cause this error to appear and tried compiling again. I got the same same error. Arrugh!

So, my good fellows, Windows enthusiasts, and WiX users, there falls two questions:

  • Is a typelib something that WiX can register natively? If so, how?
  • If not, what's the proper way of registering a typelib with a windows installer?

Also, I guess as another part of this, how does Visual Studio determine how to register the typelib? (Edit: looks the MSDN library article on typelib registration has the names of the keys needed, but I still need to figure out how to get the uuid's. (This is from this blog post on typelib and COM registration by Larry Osterman.) ) Reading a bit more, It may fall to me to register these bits manually, but I hope not…

I evaluated the output from regasm /regfile:MyDll.dll MyDll.dll. It looks like these are the same keys that wix generates for the dll. Regasm's other mode, regasm /tlb:<filename> generates and registers the typelib for the assembly, but,

/regfile[:FileName] Generate a reg file with the specified name
instead of registering the types. This option
cannot be used with the /u or /tlb options

seems the /regfile switch is incompatible with the /tlb switch. Khaaaaaaaan!

Further update: It looks like you don't actually need to include the .tlb file. According to this post on wix's typelib element, an MSI can create/register this as part of the setup process. It all comes down to configuring the WiX document to actually install it by getting the right attributes.

I found out later that you can get the right attributes using heat on the .tlb directly! See this SO question for more information.

Best Answer

You should use Heat (WIX 3.0) located in the bin directory of the version you are using. Have a look at this blog post, we use it here to register all our COM objects, by creating a wix fragment...

something like

heat file MyComExposedLibrary.dll -out MyComExposedLibrary.wxs

After, reading your edit, I would create a basic msi with wix that installs the com object only, see if that works ... then you'll know which battlefield to attack ...

Related Topic