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).