Wix: Conditional deferred custom action
We have a custom action that we want to run ONLY on a major upgrade. Trouble is, the CA is deferred because it needs access to system files (it removes the old version of the program from an INI file). Because the CA is deferred, it only has access to the CustomActionData property.
So my first attempt was to set CustomActionData if UPGRADINGPRODUCTCODE was true, and then condition the CA that actually did the upgrade on CustomActionData. That failed--CustomActionData was not set, I assume because it's only visible within the custom action and not usable as a condition for the custom action.
Here are the CA's I defined:
<CustomAction Id="MyCA.SetProperty" Return="check" Property="MyCA"
Value="[UPGRADINGPRODUCTCODE]" />
<CustomAction
Id="MyCA"
BinaryKey="MyIniProcessingProgram"
ExeCommand="MyArgs"
Execute="deferred"
Impersonate="no"
Return="ignore"/>
And here is my InstallExecuteSequence:
<RemoveExistingProducts After="InstallValidate" />
<Custom Action="MyCA.SetProperty" Before="InstallFinalize"/>
<Custom Action="MyCA" After="MyCA.SetProperty">
CustomActionData
</Custom>
I have also tried:
- Making MyCA.SetProperty conditional on UPGRADINGPRODUCTCODE, then scheduling MyCA after it--doesn't work because even if MyCA.SetProperty doesn't run, the "After" action does.
It would be best if we could avoid JavaScript/VBScript actions, or resort to checking the value of CustomActionData within the INI-u开发者_JS百科pdating program itself; the idea is to make the CA itself conditional, so we don't launch it unless the condition (major upgrade) is true.
Why not use this custom action:
<CustomAction
Id="MyCA"
BinaryKey="MyIniProcessingProgram"
ExeCommand="MyArgs"
Execute="deferred"
Impersonate="no"
Return="ignore"/>
with this InstallExecuteSequence?
<Custom Action="MyCA" After="InstallValidate">
UPGRADINGPRODUCTCODE
</Custom>
Please note that UPGRADINGPRODUCTCODE is set in the package which is being upgraded, so it's available only in the uninstall process of the old version.
If you want to detect an upgrade in your new version, you can use the ActionProperty column in Upgrade table: http://msdn.microsoft.com/en-us/library/aa372379(VS.85).aspx
Basically, you need to define the upgrade rules for older and newer versions: http://wix.sourceforge.net/manual-wix2/wix_xsd_upgradeversion.htm
This way you can detect older versions through a custom property. This property can then be used to condition your custom action.
The conditions used to gate any action (deferred included) are those of the immediate sequence. That means you could use UPGRADINGPRODUCTCODE
directly as part of the condition on even your deferred action.
When the installer reaches this sequence during the immediate phase, it will evaluate the condition, and schedule the deferred execution if the condition is true. Then when it runs the deferred sequence, it will just run all the actions that were scheduled during the immediate phase.
精彩评论