RobMensching.com /Blog
WiX, Live Mesh and more.

Posted by
Rob Mensching
Friday, August 17, 2007 3:21 AM

Under
setup

10 Comments

Zataoca: Custom actions are (generally) an admission of failure.

The title of this blog entry is a concept that I kept trying to sneak into one of my earlier posts on this "Zen and the Art of Custom Actions" thread.  I finally gave up trying to make it a bullet point and now here we are.  What convinced me that there was a full topic to be covered was when I realized I meant two things when I said "Custom actions are (generally/typically) an admission of failure."

First, as a setup developer you really shouldn't have to write any custom actions*.  I know a lot of people think writing custom actions is more fun than simply declaring everything that needs to be installed.  However, custom actions are invariably more error prone than the native engine functionality.

There are three common reasons custom actions are introduced.

a.  The setup developer wrote a custom action that was already supported by the underlying engine.  This is essentially reinventing the wheel with a less stable solution.  Invariably this comes down to lack of documentation or lack of effort on the developer's part.  Either way a failure to use the most optimal solution.

b.  The setup developer wrote a custom action to address some complexity in his or her application.  As I have noted a great many times before, setup is "where the rubber meets the road" for the first time for most applications.  When issues arise often there is pressure to just solve the problems in setup rather than go back and fix/simplify the application.  Often deciding to complicate setup will lead to more fragile solutions than if the application had just been updated.  Either way the failure is often rooted in a poor design.

c.  The setup developer wrote a custom action to configure some platform because the platform technology didn't provide installation primitives for itself.  This one is just sad and, unfortunately, happens more often than not.  My favorite platform to pick on is the Internet Information Services or IIS.  The ever popular platform for ASP.NET that hosts a great many web sites around the globe provides basically no mechanisms to enable install, uninstall, rollback, upgrade and patching of web sites, virtual directories, app pools, etc.  The platform failed the setup developer.

There is a variation on c. where the setup developer wrote a custom action because his or her authoring environment doesn't support all the functionality of the installation engine.  In this case, I would encourage the setup developer to find a better authoring environment.

The second reason I say, "Custom action are an admission of failure" is that if you have a custom action then you are far more likely to have installation failures.  Having written a great number of custom actions for the WiX toolset (to try and help address c. above) I can assure you that getting the code right in all cases (especially patching) is extremely difficult.  If you look at the last bugs in WiX v2, you'll find they have all been custom action issues.  An installation package with no custom actions is far less likely to fail than a package with custom actions.

So, ultimately, I would encourage all setup developers to be very skeptical about custom actions and continually work to reduce the amount of custom code in your installation package.  There are few setup experiences more stable than an application that simply needs a bunch of files installed.  Get in the habit of questioning the value of every setup requirement beyond copying files and you may be surprised how stable things can be.  You'll also be quite a few steps down the path of Zen and the Art of Custom Actions.

 

* Note: when I talk about custom actions in this blog entry (and most blog entries) I do not mean the simple Type 51 property assignment operations that are technically defined as a custom action in the Windows Installer.  Type 51 custom action are rarely the cause of an installation failure (although you can certainly cause failures by assigning the wrong thing to the wrong place at the wrong time).

 


10 Comments

Comment by
Dmitry Pavlov
Friday, August 17, 2007 4:26 AM

Hi Rob,

Thanks for the post! My experience already convinced me that the using custom action is not very sweet thing. But how can I call the external executable (which is not part of my installation) without the custom action?

Can you please provide some guidance as to the possible strategy for such needs?

Thanks,

Comment by
James Snape
Friday, August 17, 2007 5:24 AM

A large class of custom actions do what I would call configuration - create vdirs, install another database etc. The reason I believe it is configuration and not install is due to the fact that configuration needs to be changed - you don't re-run the installer to do that, you run a configuration tool. Especially when what starts out as "install a database" turns into "can I install another copy of the database for testing?".

For these custom actions I recommend that my cutomers write a tool in their favourite language to configure the system. They can then either launch the tool from the installer or whatever mechanism available to get the user to configure their application.

James.

Comment by
Mike.
Friday, August 17, 2007 6:29 AM


I couldn't tell you how many arguments I have had with Developers/Architects/Managers over this issue.
Of all the custom actions that I have written over the years, %90 of them was to address deficiencies in the application or build system.



Comment by
Christopher Painter
Friday, August 17, 2007 10:06 AM

Come back to earth, Rob. Setup isn't xcopy. Also, while it would be a really good thing, setup developers rarely get to dictate application design. Sucks, ya I know... but them's the breaks kid.

I agree with a lot of your points, but it would be better to look back at the Windows Installer team and ask where is support for stories that currently require custom actions rather then blaming it on other teams and tools vendors.
I've been saying this for years but it always falls on death ears. This forces authoring tools vendors to do it themselves and the resulting bashing they take when it's less then perfect.



Comment by
Brad Butts
Monday, August 20, 2007 10:05 AM

I use custom actions to shell out commands to aspnet_regiis, cacls, and other command line utilities. Am I missing something? Is there a better way to do these operations in Windows Installer?

Comment by
Davidson Corry
Monday, August 20, 2007 12:50 PM

With respect, Christopher, Rob's right.

Sadly, you're right, too: install specialists' arguments often do fall on deaf ears, and setup devs don't get to dictate app design. But they do get to NEGOTIATE app design.

We -- any professional, really -- have an obligation to educate, and to push back when a bad design decision is made. Because the install environment is so different from general programming (prereqs not in place? no .NET yet? deferred actions? elevated privilege? what's an "install sequence", Daddy?) most devs and managers DON'T KNOW that what works in day-to-day programming won't work here. Who else is going to tell them? Who else is going to push the vendors to make better tools?

Do we win all the arguments? No. Do we win even most of them? It is to laugh. Frustrating much? Like swimming up a dry waterfall sometimes.

But it still beats working for a living, don't it? <grin>

Comment by
Christopher Painter
Tuesday, August 21, 2007 7:20 AM

IMHO, the only way to overcome this is for the development technologies to be prebaked with patterns that are actually designed in cooperation with the Windows Installer team. This way developers will be guided towards good design ( from a setup prospective ) without ever even knowing they were doing it. If these technologies ever reached this point of maturity, I would gladly stop writing CA's. Until then it rarely does any good for me to correct any but the most glaring or low hanging problems that my dev teams create.

Comment by
PhilW
Thursday, August 30, 2007 8:32 AM

I agree with James Snape. The (often unquestioned) assumption here is that you need to do things like create databases and websites during the MSI install. When people go down that path there's a lot of anguish about the complications of custom actions (elevation, impersonation, rollback, debugging, why don't these guys like installer classes etc). It's often more cost-effective to do these things in a bootstrap or chainer or an application configuration program where the code is in a normal application environment with advantages such as easier debugging. Things like creating and populating databases aren't rocket science unless you're doing them inside an MSI setup.

Comment by
Christopher Painter
Tuesday, September 18, 2007 1:16 PM

I guess I'm just not afraid to bake configuration patterns into an install. To me, it makes perfect sense for an admin/user to go to Add/Remove Programs and hit the Change button to invoke a MaintenanceUI story that includes making changes to choices that were first inputted during the initial install. To me it beats every application having it's own configuration utility.

Still it can be a vey difficult road to plow trying to do all of this in MSI so if the development team can hand over a competent configuration utility, I'll deploy that instead. Unfortunatly as several of my friends can attest to, I've seen development teams turn out extremely horrible configuration utilities and the install team is just left looking stupid because people don't understand where the install ends and configuration begins. They just know the experience wasn't what they were looking for.

Case in point would be MySQL. They abstracted configuration to a seperate utility but there is one huge problem with it IMHO: A complete lack of data driven / silent configuration.

Comment by
Tony
Sunday, August 31, 2008 12:19 PM

I agree with Rob that CAs should be avoided but even more with Christopher that installer should have done more to support repetitive and fairly standard use cases.

It should have been possible to:
a) invoke standard action multiple times
b) make standard action work on different tables and/or subsets of a table
c) invoke CA to initialize GUI dialog
d) use condition on components not only during install but during uninstall and patch application

There would be less need for CAs if it were possible to use standard action in a more flexible way. And I am not talking about Web site, database installations or similar but about 'plain' installations that just create/delete/modify files and folders and Registry keys/values.

Leave a Comment

(optional)