Wix 3.11下使用VBScript条件设置注册表值的异常问题咨询
Wix VBScript自定义脚本读不到RegistrySearch属性值解决方案
核心问题原因
你遇到的SHELL_KEY为空是两个常见问题共同导致的:
- 自定义动作执行时机早于AppSearch标准动作:RegistrySearch的查询逻辑属于Wix内置的
AppSearch标准动作执行阶段,你当前配置的Before="CostFinalize"没有限制在AppSearch之后执行,大概率脚本运行时RegistrySearch还没完成查询,属性自然为空 - 32/64位注册表重定向:默认32位Wix安装包在64位系统上运行时,会自动将HKLM\SOFTWARE的查询重定向到
HKLM\SOFTWARE\Wow6432Node路径下,而Winlogon的Shell值存储在64位原生注册表路径中,导致查询返回空
修改步骤
- 调整自定义动作执行时机,指定在
AppSearch动作完成后执行,同时在InstallUISequence和InstallExecuteSequence两个序列中都注册该动作,避免UI安装流程下属性未赋值 - 给RegistrySearch添加
Win64="yes"属性,强制读取64位原生注册表路径 - 给公共属性添加
Secure="yes"标记,避免提升安装权限时属性值丢失
修改后完整代码示例
<Wix> <Product> ... <!-- 给属性添加Secure标记,避免权限提升时丢失 --> <Property Id="SHELL_KEY" Secure="yes"> <RegistrySearch Id="REG_SHELL_KEY" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" Name="Shell" Win64="yes"/><!-- 强制读取64位注册表 --> </Property> <Property Id="RESET_SHELL_KEY" Secure="yes"/> <CustomAction Id="REGISTRYKEYCHECK" Script="vbscript" Execute="immediate" Return="ignore"> <![CDATA[ Dim value value = Session.Property("SHELL_KEY") ' 加非空判断避免空值触发函数报错 IF NOT IsNull(value) AND NOT IsEmpty(value) AND INSTR(1, value, "thisAppName.exe", vbTextCompare) > 0 THEN Session.Property("RESET_SHELL_KEY") = "1" END IF ]]> </CustomAction> <InstallExecuteSequence> <!-- 指定在AppSearch查询完成后执行 --> <Custom Action="REGISTRYKEYCHECK" After="AppSearch">1</Custom> </InstallExecuteSequence> <!-- 新增UI序列动作注册,覆盖带UI的安装流程 --> <InstallUISequence> <Custom Action="REGISTRYKEYCHECK" After="AppSearch">1</Custom> </InstallUISequence> ... <Directory> ... <Component Id="ResetShellExe" Guid="{....}"> <Condition><![CDATA[RESET_SHELL_KEY="1"]]></Condition> <!-- 写入注册表也指定64位路径,避免重定向到Wow6432Node --> <RegistryKey Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" Win64="yes"> <RegistryValue Type="string" Name="Shell" Value="$(var.MyProgram.TargetFileName)" KeyPath="no"/> </RegistryKey> </Component> <Feature Id="Complete" Level="1"> ... <ComponentRef Id="ResetShellExe"/> </Feature> ... </Product> </Wix>
额外优化点
- 脚本中新增了空值判断,避免SHELL_KEY为空时INSTR函数抛出异常
- 组件条件明确写为
RESET_SHELL_KEY="1",避免默认隐式布尔判断的兼容性问题 - 写注册表的组件也添加了
Win64="yes",确保写入64位原生路径,不会被系统重定向到32位注册表目录导致修改不生效
内容的提问来源于stack exchange,提问作者Paul Cronk
相关产品推荐
相关产品推荐

