RobMen's Recommendation: Do not advertise COM information in MSI.

This is a topic that I planned to cover a long time ago. Later I realized that it takes quite a bit of explanation and code to demonstrate why advertising COM information is such a bad idea. Recently, I've had a number of people all ask about this topic again, so I thought I'd sit down for a few hours and put the example together.

To be very specific, what I'm talking about is avoiding the use of the Class, ProgId, and MIME tables and to a lesser extent the Extension and Verb tables. Using WiX toolset parlance, I'm talking about not specifying "yes" for the Advertise attribute on the elements with the same name as the tables above.

A lot of people think that my recommendation to avoid advertising COM information means they should avoid using the Class, ProgId or MIME WiX elements. I am not. Those elements can greatly simplify your setup code; just don't set the Advertise attribute to "yes" (the default is "no"). The WiX toolset will take care of generating the correct Registry rows for you using stable identifiers.

So why do I recommend not advertising COM information? There are two reasons. First, COM advertisement can cause unexpected repair behavior. In particular, the Windows Installer will repair other products that share the advertised COM information. Second, these repair situations can require the user to provide the source for the advertised product which may not be the product the user is actually using. The user will experience this undesirable repair behavior until they fulfill the source requirement. This second issue is the real reason I discourage people from using COM advertisement.

Historically, I've had some people argue (quite vehemently) with me that the repair behavior cannot actually happen. I'm going to go write some code now to demonstrate the problem. Be back later...

Okay, it is a day later (had to actually do real work today <smile/>) and I now have two example packages up on my web server so you can play along from home (link in step 0 below). These are modifications to my "Fruit Server" demo.

For those of you that have never seen it, the "Fruit Server" is silly piece of code that you can call and it will randomly return you the name of some fruit. The Fruit Server is implemented as both a DCOM Windows Service (native code, with a command-line client) and a Web Service (web browser is a client). I use these programs to demonstrate how to do setup for "Windows things" and "Web things" in one place. In this particular demo, I only needed the DCOM Service so I left out the Web Service.

Finally, to demonstrate the problem I provide "fs.msi" which is the normal "Fruit Server" that doesn't advertise anything and "fs2.msi" which is "The Other Fruit Server" that can advertise its DCOM proxy stub. Those two installs will create directories in the ProgramFilesFolder with their respective names, so you can easily tell when they are fully installed. Now, let's get on with the show.

0. Download the and unzip it to C:\demo

1. Open up a command prompt: Start -> Run -> cmd.exe

2. Open up explorer window to ProgramFilesFolder: start "" "%ProgramFiles%"

3. Scroll to the bottom of your ProgramFilesFolder explorer to see where new directories will be created.

4. Install "Fruit Server": msiexec /i C:\demo\fs.msi

5. Notice that "%ProgramFiles%\Fruit Server" is created in explorer.

6. Run the Fruit Server client to get a fruit: "%ProgramFiles%\Fruit Server\FsClient.exe"

7. Advertise "The Other Fruit Server": msiexec /jm C:\demo\fs2.msi

8. Notice that "%ProgramFiles%\The Other Fruit Server" is not created. That's because only the advertised entry points are registered. In this case, only the DCOM proxy stub.

9. Run the Fruit Server client to get another fruit: "%ProgramFiles%\Fruit Server\FsClient.exe"

10. Notice that it takes a second for the Fruit Server client to return a fruit. Then notice that the "%ProgramFiles%\The Other Fruit Server" folder was created!

These 11 steps demonstrate the first behavior I was talking about. The execution of one program is suddenly affected by the installation of a second program. To be specific, the entire feature in the second program that was advertised gets faulted in. If that second program has hundreds of megabytes in an advertised feature (not a great design to begin with) the DCOM activation must wait for the install to complete.

Okay, that behavior isn't so great but let's look at the second issue. This one is a the real kicker in my mind.

0. Uninstall both of the installed programs. msiexec /x C:\demo\fs.msi & msiexec /x C:\demo\fs2.msi

1. Advertise "The Other Fruit Server": msiexec /jm C:\demo\fs2.msi

2. Rename "The Other Fruit Server" package to simulate the CD being ejected: move C:\demo\fs2.msi C:\demo\fs2x.msi

3. Install "Fruit Server": msiexec /i C:\demo\fs.msi

4. Launch the Fruit Server client to get a fruit: "%ProgramFiles%\Fruit Server\FsClient.exe"

5. Notice the source resolution prompt from the Windows Installer! Notice even more closely that the prompt is asking for the path to the fs2.msi!

6. Hit cancel (maybe three or four times) to get your fruit. Repeat step 4 and notice you always get prompted.

7. Rename "The Other Fruit Server" package to allow you to remove it: move C:\demo\fs2x.msi C:\demo\fs2.msi

I hope you agree that this is pretty "wonky" behavior. Even more users absolutely hate source resolution prompts, so if you did the work to ensure you avoid source resolution prompts another program could totally screw you up. Finally, even if users did like the prompts you have to admit it is very strange that your program is asking for the source media for a completely different program.

Now some people will argue that you should use COM advertisement to improve the reliability of your program. Personally, I don't see how one can argue that the side effects that COM advertisement exposes a program to can be considered reliability improvements. If someone really wants to build reliability around their COM activation then I would highly recommend not advertising COM information, handle the error codes returned from ::CoCreateInstance() (and friends), and then repair the application using the MSI APIs. Using this method, you have far more control over the Windows Install repair behavior.

Finally, I considered titling this blog entry, "Why you can and should ignore ICE33" but that title wouldn't be quite accurate. For example, ICE33 also catches Extension and Verb registry keys. IMHO, advertised Extension and Verb elements, like shortcuts, provide very logical user entry points to cause your application to get installed or repaired. A user that double clicked on a file then saw an application begin to install is far less likely to question a source prompt (if the application can actually open that file extension) than if a program internally kicked off a repair and prompted for some other programs original media.

Oh, and before I wrap this blog entry up, anytime someone suggests you should ignore an ICE warning, you really should do your homework to understand why. Hopefully this blog entry finally clears up all the complex behavior that explains why I don't recommend you advertise COM information and acknowledge but ultimately ignore the ICE33 warnings.

FireGiant provides dedicated support for the WiX toolset. Ever wish you could get your WiX questions answered immediately with the technical detail that you find in the blog posts here? You can with FireGiant!

Send a comment

Something went wrong while submitting your comment. You can try again.

Thank you for sending your comment.