Core: Essentially custom actions are complex to get right because of complexity arising from:
Sequencing-
, Conditioning-
(when it runs - in what installation mode: install, repair, modify, uninstall, etc...) and Impersonation-issues
(security context it runs in).
- It results in overall
poor debugability
- very hard hard work to test in all permutations.
Application Launch: Solution? Prefer application launch code. You get a familiar debugging context and can usually keep the code in the main application source - very important. The issue is the same for: licensing in setups (take it out if you can).
Custom Action Debugging: With all warnings in (you will read the short "folksy" version below - yes you will - Jedi trick) - do use built-in constructs when available - here is how you can improve debugging custom actions though:
Short "Folksy" Version:
Overall: a modern setup should be "declared", not coded. "think SQL queries, not scripting". Apply well-tested logic that you just invoke to do the work. More on that later.
- Avoid custom actions if you can.
- They will screw with your head (and do murder to your girly figure)!
- Seriously: they are the number one cause of deployment failure.
- They feature a "conspiratory complexity" whereby things often break unexpectedly and without warning after you have deployed your setup for some time and it is "in the wild".
- Deployment is a process - you will have to deal with "past sins" for every new release. It can become a real nightmare to clean things up after broken deployments. Each iteration adds new, potential error sources (my fix for my failed fix, failed, etc...).
- Runtime requirements for managed code and scripting custom actions are very error prone (.NET in particular in my opinion). A setup - if anything - should feature "minimum dependencies" - since it is used to install dependencies outright and should run on "any machine" in "any state" in "any language".
- Apart from using built-in MSI constructs or WiX custom features, custom actions can often be avoided by minor changes to the application design so that complex custom actions are no longer needed (samples below).
- Spend the time to find and review built-in MSI features and extensions from WiX, Installshield, Advanced Installer (and other vendor tools).
- These extensions are made by the best deployment experts available, and have in most cases been tested by thousands of people (millions and billions in the case of built-in MSI features).
- How can you conceivably match this with your own proprietary code? If the existing solution is good enough - which it normally is - then your own code is entirely added risk for no gain whatsoever. The ready-made solutions even support rollback - a notoriously neglected and hard-to-implement feature - that is actually required by design.
- In other words: when you use the existing solutions, you borrow not just the implementation, but crucially also the QA, UAT and testing of the extensions when you use them. This can save weeks of work and contribute greatly to deployment stability.
- All that is needed is to spend some time searching and reading up on what is already available, rather than jump-starting things with your own code. Heck, even your own manager could get involved searching... In a dream world.
- A setup should generally not be coded, it should be declared! (think SQL). This is what Windows Installer is all about: you declare what to be installed, and the sequence is taken care of by the installer engine itself. Benefits result - when done right.
- That's about it really. Read on if you dare! Here be dragons in the midst of serious ranting. And crucially: real-life experience from dealing with both setup development, and also large scale deployment of such setups in corporate environments. Common problems become clearer - they are more identifiable. And you may get burned with problems you really have to answer for - that you feel you could never have foreseen (doing corporate packaging and repackaging you get to see just how much can be wrong with a single package - it can take days to beat them into shape at times).
- Please remember, and this is not meant as bad as it sounds: deployment is generally a low status technology endeavor, but a high profile failure. Errors really show. And someone will get to answer for it, and support will really feel it.
- Debugging during development is hard, but for deployment it is sometimes nearly impossible since you generally have no access to the problem systems, and each problem system will be in a totally different state.
- In all honesty: failing to get software deployed correctly to end users may be close to being the most expensive error to make in software development - nobody can witness the greatness of your solution - and it affects sales, support, marketing and further solution development.
- Poor deployment can definitely sink a product. Unfortunately good deployment isn't enough to save a product.
Fleshed Out Ranting Version :-)
As stated above this section was split from an existing answer with broader scope: How do I avoid common design flaws in my WiX / MSI deployment solution? (an answer intended to help developers make better deployment decisions).
- Erroneous or unnecessary use of custom actions.
A plethora of deployment problems can be caused by custom action use - most of them very serious. If your setup fails to complete or crashes, it is a fair bet that a erroneous custom action is at fault.
Accordingly the obvious solution is to limit your use of custom actions whenever possible. Custom actions are (often) "black box" (hidden code) whereas most of MSI features a lot of transparency. The MSI format can be viewed easily (COM-structured storage file), and everything that an MSI file does can essentially be deduced from its MSI database file - with the exception of compiled custom actions (script custom actions are still white box - you can see what is going on, unless they are obfuscated).
In this age of malware, these black box custom actions - that run with elevated rights - may become frowned upon in more ways than one. They are not just stability and reliability issues, but a full-blown security issue.
6.1 The Overuse of Custom Actions
Pardon the "trifles" listed below. A lot of this may be banality, but maybe use the arguments listed to make a case for yourself to avoid custom actions and to work on better solutions - usually involving smarter application launch sequence and application self-configuration. Trust us, application coding will be more interesting than dealing with Windows's Installer's complex conditioning, sequencing and impersonation for custom actions.
The below has been updated so many times that sections are a little bit out of sequence or repetitive here and there. Will be cleaned up as time allows.
Developers are good at coding - so with all due respect - you tend to overuse custom actions to do things that are better done using built-in MSI features or ready-made MSI extension solutions such as those available in WiX for advanced things such as XML file updates, IIS, COM+, firewall rules, driver installation, custom permissioning for disk and registry entries, modify NT privileges, etc... Such support is also found in commercial tools such as Installshield and Advanced Installer.
It is also possible to do a lot of what is done in custom action as part of an application's launch sequence. The prime example is initializing user data and copying settings file to each user profile. There is a little summary of this issue here: Create folder and file on Current user profile, from Admin Profile.
It is obvious, but very often custom actions are used out of ignorance of what is already available "out of the box" by means of ready-made solutions. This happens to all of us all the time, doesn't it? There is always some smarter way to do things that would have saved you lots of grief? In general anyway - though sometimes you are breaking new ground. Don't break new ground in your setup - unless you absolutely have to! Save it for your application.
I want to emphasize that these built-in Windows Installer solutions and extensions from WiX and commercial tools have been written by the best deployment specialists available. And moreover, and even more importantly, they have been used and tested by thousands, millions - heck even billions of people for built-in MSI features. Do you really think you can do any better? Moral of the story: pick your battles and use your great coding skills to solve new problems, and let deployment be as dumb as possible. Use what already works, and don't re
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…