WiX延迟CustomAction中CustomActionData在ExeCommand取值为空问题排查
问题:Deferred CustomAction无法将CustomActionData解析到ExeCommand中
我尝试将INSTALLDIR传递给deferred类型的ExeCommand CustomAction,为简化复现仅调用echo [CustomActionData],代码如下:
<CustomAction Id="SetInstallationDirectory" Property="RunEcho" Value="[INSTALLDIR]" /> <CustomAction Id="SetFoldersFilesToNotWrite" Property="CmdPath" Value="cmd.exe" /> <CustomAction Id="RunEcho" Execute="deferred" Impersonate="no" Property="CmdPath" ExeCommand='/c echo "[CustomActionData]"' Return="ignore" /> <InstallExecuteSequence> <Custom Action="SetInstallationDirectory" After="CostFinalize">NOT Installed</Custom> <Custom Action="SetFoldersFilesToNotWrite" After="CostFinalize">NOT Installed</Custom> <Custom Action="RunEcho" After="InstallFiles">NOT Installed</Custom> </InstallExecuteSequence>
运行安装包后,日志显示:
MSI (s) (BC:6C) [19:01:42:524]: PROPERTY CHANGE: Adding RunEcho property. Its value is 'c:\InstallerTest\'. ... MSI (s) (BC:6C) [19:01:53:213]: Executing op: ActionStart(Name=RunEcho,,) Action 19:01:53: RunEcho. MSI (s) (BC:6C) [19:01:53:214]: Executing op: CustomActionSchedule(Action=RunEcho,ActionType=3186,Source=cmd.exe,Target=/c echo "",CustomActionData=c:\InstallerTest\) ...
可见CustomActionData已经正确获取到目录路径,但ExeCommand却被解析为/c echo ""而非预期的/c echo "c:\InstallerTest\",请问代码哪里有问题?(使用WiX v3.14.1)
问题原因与解决方案
核心问题
Deferred类型的ExeCommand CustomAction中,[CustomActionData]的解析逻辑依赖于CustomAction的Property属性必须设置为自身ID。你当前将RunEcho的Property设为CmdPath,导致MSI无法将存储在RunEcho属性中的CustomActionData关联到ExeCommand的变量解析上,最终[CustomActionData]被替换为空字符串。
修正代码
调整RunEcho的Property属性为自身ID,并可以简化CmdPath的定义(直接将cmd.exe整合到Source中):
<CustomAction Id="SetInstallationDirectory" Property="RunEcho" Value="[INSTALLDIR]" /> <CustomAction Id="RunEcho" Execute="deferred" Impersonate="no" Property="RunEcho" <!-- 改为与CustomAction同名的属性 --> Source="cmd.exe" <!-- 直接指定程序路径 --> ExeCommand='/c echo "[CustomActionData]"' Return="ignore" /> <InstallExecuteSequence> <Custom Action="SetInstallationDirectory" After="CostFinalize">NOT Installed</Custom> <Custom Action="RunEcho" After="InstallFiles">NOT Installed</Custom> </InstallExecuteSequence>
逻辑说明
- 当
Property属性设置为CustomAction自身ID时,MSI会自动将该属性的值作为CustomActionData,供ExeCommand中的[CustomActionData]变量解析使用。 - 修正后,日志中的Target会变为
/c echo "c:\InstallerTest\",符合预期。
内容的提问来源于stack exchange,提问作者Totem
相关产品推荐
相关产品推荐

