Wix v3 Installer:自定义操作参数传递失败问题及解决方法
WiX v3 延迟自定义操作无法获取参数的问题与修复方案
开发大型WiX v3安装程序时,需通过C#自定义操作实现复杂条件下的注册表项添加逻辑。测试基础框架时,发现无法从wxs文件向延迟执行的C#自定义操作传递参数,自定义操作端始终获取不到参数值。
原问题代码
product.wxs 文件
<Binary Id="CustomActionBinary" SourceFile="$(var.RegistryManagementCustomActions.TargetDir)$(var.RegistryManagementCustomActions.TargetName).CA.dll" /> <CustomAction Id="CustomActionAddRegistryEntries" Impersonate="no" BinaryKey="CustomActionBinary" DllEntry="AddRegistryEntries" Execute="deferred" Return="check" /> <CustomAction Id="CustomActionAddRegistryEntriesProperty" Property="CustomActionAddRegistryEntries" Value="Arg1=1;Arg2=2;Arg3=3;INSTDIR=[INSTALLFOLDER]" /> <!--Installation Sequence--> <InstallExecuteSequence> <!--add registry entries upon install--> <Custom Action='CustomActionAddRegistryEntries' After='InstallInitialize'>NOT Installed</Custom> <!--remove registry entries upon uninstall--> <Custom Action='CustomActionRemoveRegistryEntries' After='InstallFinalize'> (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") </Custom> </InstallExecuteSequence>
C# 自定义操作文件
[CustomAction] public static ActionResult AddRegistryEntries(Session session) { CustomActionData data = session.CustomActionData; string ss = data.Count.ToString() + "\n"; foreach (var k in data) { ss += k.Key + ";" + k.Value + "\n"; } //Access arguments //string arg1 = session.Format(data["Arg1"]); session.Log("Begin adding registry entries"); string s = "Running AddRegistryEntries"; s += "\n" + ss; File.WriteAllText(@"C:\Users\Bhairav\Desktop\customactiontest.txt", s); return ActionResult.Success; }
修复方案
关键修复逻辑
延迟执行的自定义操作无法直接访问安装会话中的属性,必须通过属性传递型自定义操作提前将参数绑定到目标自定义操作的属性中,并且该属性传递操作需要在CostFinalize之后执行(此时目录类属性如INSTALLFOLDER才会生成正确值),同时要确保该属性传递操作被加入到执行序列中。
修改后的 product.wxs 文件
<Binary Id="CustomActionBinary" SourceFile="$(var.RegistryManagementCustomActions.TargetDir)$(var.RegistryManagementCustomActions.TargetName).CA.dll" /> <CustomAction Id="CustomActionAddRegistryEntries" Impersonate="no" BinaryKey="CustomActionBinary" DllEntry="AddRegistryEntries" Execute="deferred" Return="check" /> <CustomAction Id="CustomActionAddRegistryEntriesProperty" Property="CustomActionAddRegistryEntries" Value="InstallDir=[INSTALLFOLDER]" /> <CustomAction Id="CustomActionRemoveRegistryEntries" Impersonate="no" BinaryKey="CustomActionBinary" DllEntry="RemoveRegistryEntries" Return="check" /> <!--Installation Sequence--> <InstallExecuteSequence> <!--add registry entries upon install--> <Custom Action="CustomActionAddRegistryEntriesProperty" After="CostFinalize" /> <Custom Action='CustomActionAddRegistryEntries' After='InstallInitialize'>NOT Installed</Custom> <!--remove registry entries upon uninstall--> <Custom Action='CustomActionRemoveRegistryEntries' After='InstallFinalize'> (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") </Custom> </InstallExecuteSequence>
修改后的 C# 自定义操作文件
[CustomAction] public static ActionResult AddRegistryEntries(Session session) { CustomActionData data = session.CustomActionData; string installDir = data["InstallDir"]; session.Log("Begin adding registry entries"); session.Log("InstallDir = " + installDir); return ActionResult.Success; }
内容的提问来源于stack exchange,提问作者Bhairav Thakkar
相关产品推荐
相关产品推荐

