Managed Code CustomActions, no support on the way and here's why.
I was recently pinged by a triumvirate of individuals asking me about using managed code to write CustomActions. This is a hot topic that comes up about every other month on the wix-users mailing list at SourceForge. Those of you that hang out on that mailing list know that I've repeatedly stated that the WiX toolset does not support managed code CustomActions because the Windows Installer team does not support managed code CustomActions.
However, since I was asked by three people (all of them knowledgeable and respectable) at the same time I thought I would again ask the Windows Installer team about supporting managed code CustomActions. I got the same answer I got last time, “The Windows Installer does not support CustomActions written in managed code.” However, this time we had time to have a deeper conversation about why the managed code is not supported for CustomActions. There are essentially two reasons managed code is not supported: one technical, one strategic.
Technical
The technical issue that managed code CustomActions have is due to the fact that the .NET Framework is “sticky” (Carolyn, MSI Dev Lead, used the phrase “tattoos your process”). Once you load a version of the .NET Framework into a process, the .NET Framework is not unloaded. More importantly, if you attempt to load a different version of the .NET Framework into your process later you will get the previously loaded version.
I have to admit this technical issue with using managed code in CustomActions surprised me. I had heard of the problem before (of course, Carolyn had mentioned it a few times) but I didn’t truly understand the ramifications until I wrote the code tonight then stepped through it in the debugger. It is kinda’ cool to see the .NET Framework v1.1 get loaded by one CustomAction then later have a second CustomAction try to load the .NET Framework v2.0, get the v1.1 Framework handed to it, then fail when trying to create an app domain later. Well, it’s only cool because I anticipated the failure.
What this mean is that if you end up in a scenario where you have a CustomAction written for one version of the .NET Framework and a second CustomAction written for a different version of the .NET Framework that your second CustomAction will fail before it can even get started. Well, you could mark your .NET Framework 1.1 CustomAction to say that it will run in the .NET Framework 2.0 and then try to ensure that the .NET Framework 2.0 is loaded everywhere. That might work until there is another .NET Framework version (4.0?).
There is additional complication on Windows Server 2003. On that OS, the Windows Installer will attempt to load the .NET Framework 1.1 into the deferred CustomAction server (for a reason that Carolyn mentioned but I’ve forgotten now, should have taken better notes). If you have already loaded the .NET Framework 2.0 (say, for a CustomAction) then the Windows Installer can fail to add files to the Global Assembly Cache.
All of these complications when managed code CustomActions are introduced reduce the chances that an installation package will successfully install and uninstall (let alone upgrade or be patchable). When you approach the problem from a platform point of view (as the Windows Installer team must), I hope you agree that there are way too many common failure cases to support managed code CustomActions.
Now the intrepid developer might suggest that managed code CustomActions could be hosted in a separate process from the Windows Installer’s CustomAction server. That way the separate process would disappear and take the .NET Framework with it each time the CustomAction exited. Make no mistake, this solution takes a lot of work and is most likely something along the lines of what the Windows Installer team would need to do to support managed code CustomActions.
However, they are focusing on other features because of their strategic position on CustomActions.
Strategic
Inside Windows there is a fair bit of discussion going on right now about how to improve application deployment on the operating system. Knowing about the discussions, I invited a couple of the Windows architects to my conversation with the Windows Installer team about managed code CustomActions. My hope was to provide the architects with a couple real world examples of problems facing setup developers today and maybe get some insight from them along the way. What I got was validation of something I’ve seen coming for a long while.
Strategically the goal is to reduce the number of CustomActions shipping in installation packages. It is generally accepted that a great majority of the installation failures out there today are failures inside CustomActions. CustomActions in installation packages also surface as major problem for application compatibility between operating systems. The data collected thus far suggests that application deployment would be improved by reducing the number CustomActions in installation packages.
Making it easier to create more CustomActions (which a managed code for CustomAction would certainly do) does not align with the strategic goal.
Now, having written something like 75% of the CustomActions in the WiX toolset let me assure you that I’m one of the first to point out that CustomActions are quite often a necessity today. However, I also know that the code in the Windows Installer has had far more scrutiny and testing than the WiX CustomActions to date. Thus, I can agree that it would be better if there were fewer CustomActions shipping in installation packages today and that the installation functionality was instead built into the Windows Installer or the operating system in general.
For example, imagine that to configure a web site in IIS that you didn’t need a CustomAction from the WiX toolset (or some other vendor). Instead, you just declare that you want your web site (much like you do in the WiX toolset today) and code that was installed with IIS would be activated by the Windows Installer to do the work. That means that you and I would not be responsible for reverse engineering the IIS store (i.e. the metabase) then writing the CustomAction to ship in our installation package. That would move us all a great many steps away from CustomActions and hopefully towards a more stable operating system.
Now, I know there are a good number of other things that people use CustomActions for today. I also know that it would be very convenient to be able to write CustomActions in managed code. However, today the Windows Installer does not support managed code CustomActions and the general direction appears to be to try to reduce the need for CustomActions overall.