I needed to add a CustomAction that removed the native image from the GAC. To do this I came across more slightly odd behaviour from the windows install platform so I thought I’d write a blog entry about it.
At first glance creating an uninstall action looks dead easy. Just create a custom action that does the opposite of what you did on install. In the case of ngen this is just adding an extra /delete switch, an absolute cinch! The syntax for the remove custom action is shown below. Note the use of the Return property to ignore the result, it possible that the action will fail because someone has removed the native image by hand; using the Return property this way will stop uninstallation failing if this happens.
<CustomAction Id="Test.exeFileRemoveNGen" ExeCommand='"[WindowsFolder]Microsoft.NET\Framework\v1.1.4322\ngen.exe" /delete "[#DataPharm.PharmaNet.Logging.dllFile]"' Directory="InstallDir" Return="ignore" />
Then pop a reference to this new custom action in the “InstallExecuteSequence” section of the install script. Job’s a good’un. Or so I thought.
An “normal” MSI produced by wix will have the following actions in its InstallExecutionSquence table There are many ways to added and remove stuff from this list, if you don’t do any of them this is what will be produced.
ValidateProductID 700
CostInitialize 800
FileCost 900
CostFinalize 1000
InstallValidate 1400
InstallInitialize 1500
ProcessComponents 1600
UnpublishComponents 1700
MsiUnpublishAssemblies 1750
UnpublishFeatures 1800
RemoveShortcuts 3200
RemoveFiles 3500
InstallFiles 4000
CreateShortcuts 4500
RegisterUser 6000
RegisterProduct 6100
MsiPublishAssemblies 6250
PublishFeatures 6300
PublishProduct 6400
InstallFinalize 6600
The interesting thing is an install whips though all of them on when both installation and uninstalling. On installation it starts with the lowest number and works forward, on uninstallation it starts with the highest number and works backwards. This is cool most of the time because most actions done by the installer are reversible, for example the installer knows that if you try and remover a file before you install it, it’s not a big deal.
When you add in custom actions you add extra entries to this list; which creates a problem. Most CustomActions will have problems being run both on install and uninstall. To get round this you have to give your CustomAction a condition so it will only be run on installation or installation. You can find out load of good information about condition at the Conditional Statement Syntax section of the windows installer documentation. In case you’d rather not read though that and figure it out for you’re self I’ve given the systax below.
A condition for a custom action that should only be run at install has the following format:
$ComponentName>2
A condition for a custom action that should only be run at uninstall has the following format:
$ComponentName=2
This condition should be placed inside the Custom tag that controls when the CustomAction is executed. This gives our example wix file the following format:
<InstallExecuteSequence>
<Custom Action="Test.exeFileRemoveNGen" After="MsiUnpublishAssemblies">$Test.exeComponent=2</Custom>
<Custom Action="Test.exeFileNGen" After="InstallFinalize">$Test.exeComponent>2</Custom>
</InstallExecuteSequence>
The full wix sources file is available here. Again it should compile but will not link without an available Test.exe assembly.