问题 WiX Bundle bal:condition - util:RegistrySearch变量总是为false


如果未安装第三方软件元素,我希望我的安装失败。我加了一个 Fragment 用一个 util:RegistrySearch 和a bal:Condition 到了 Bundle但我无法让它发挥作用。 ThirdPartyCOMLibraryInstalled 永远不会评估为真。我已经确认密钥存在,以及我使用的值 Key 是正确的 - 我在regedit中复制/粘贴了所选键的名称。日志中没有任何错误。

我正在使用Windows 7 64位的Visual Studio 2012中的WiXTools 3.7构建安装程序,并在Windows XP SP3和Windows 7 64位上进行测试。

在线搜索其他示例 util:RegistrySearch 我遇到了条件测试表达式的以下替代形式。

  1. ThirdPartyCOMLibraryInstalled = 0  - 永远是假的
  2. ThirdPartyCOMLibraryInstalled <> 1  - 永远是真的

这里是 Bundle 码:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
     xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension"
     xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">

    <Bundle Name="!(bind.packageName.MyApp)"
            Version="!(bind.packageVersion.MyApp)"
            Manufacturer="!(bind.packageManufacturer.MyApp)"
            UpgradeCode="a07ce1d5-a7ed-4d89-a7ee-fb13a5dd69ba"
            Copyright="Copyright (c) 2013 [Bundle/@Manufacturer]. All rights reserved."
            IconSourceFile="$(var.My_Application1.ProjectDir)MyCo.ico">

        <bal:Condition Message="ThirdParty Application COM Library Required. Please (re)install ThirdParty Application and ensure 'Windows API' and '.NET Components' are installed."
        >ThirdPartyCOMLibraryInstalled</bal:Condition>

        <Variable Name="InstallFolder"
                  Type="string"
                  Value="[ProgramFilesFolder]MyCo Systems\My_Application\"/>
        <BootstrapperApplicationRef
            Id="WixStandardBootstrapperApplication.HyperlinkLicense" >

            <bal:WixStandardBootstrapperApplication
                ThemeFile="Resources\HyperlinkTheme.xml"
                LaunchTarget="[InstallFolder]My_Application.exe"
                LocalizationFile="Resources\HyperlinkTheme.wxl"
                SuppressRepair="yes"
                SuppressOptionsUI="yes"
                LicenseUrl=""
                LogoFile="Resources/MyCoLogoWt64.png"

            />
        </BootstrapperApplicationRef>
        <Chain>
            <PackageGroupRef Id="NetFx40Redist"/>
            <MsiPackage Id ="MyApp"
                        Vital="yes"
                        Name="My Application"
                        SourceFile="$(var.MyApp_Install.TargetDir)MyApp_Install.msi">
                <MsiProperty Name="INSTALLLOCATION"
                             Value="[InstallFolder]" />
            </MsiPackage>
        </Chain>
    </Bundle>

    <Fragment>
      <util:RegistrySearch
            Variable="ThirdPartyCOMLibraryInstalled"
            Result="exists"
            Root="HKLM"
            Key="SOFTWARE\Classes\ThirdPartyId.Server\CLSID"/>
    </Fragment>
</Wix>

12022
2018-04-19 15:41


起源



答案:


根本问题是 RegistrySearch 在一个单独的 Fragment 永远不会被引用。因为什么都没有 Fragment 引用链接器“优化掉”的内容 Fragment 并且搜索不包含在您的 Bundle

除此之外:你可以争辩说,有一个事实,即在搜索中提到的变量 Condition 链接器应该能够确定搜索是必要的。但是,这并不适用于所有情况。

幸运的是,解决方案非常简单!你甚至必须从以下两种中选择一种:

  1. 移动 RegistrySearch 要素 Bundle 元件。
  2. 添加一个 RegistrySearchRef 中的元素 Bundle 元素来引用 RegistrySearch 在里面 Fragment。你还需要给予 RegistrySearch 和 Id 属性。

就个人而言,我喜欢选项二,我甚至可能会移动 Condition 进入 Fragment 以及将所有这些东西组合在一起。类似于:

<Bundle ...>
   <util:RegistrySearchRef Id='SearchForThirdParty' />

   ...

</Bundle>

<Fragment>
   <util:RegistrySearch
          Id='SearchForThirdParty' 
          Variable="ThirdPartyCOMLibraryInstalled" 
          Result="exists"
          Root="HKLM"
          Key="SOFTWARE\Classes\ThirdPartyId.Server\CLSID"/>

    <bal:Condition Message="ThirdParty Application COM Library Required. Please (re)install ThirdParty Application and ensure 'Windows API' and '.Net Components' are installed.">ThirdPartyCOMLibraryInstalled</bal:Condition>
  </Fragment>
</Wix>

应该这样做。


15
2018-04-19 16:28



这完全有效。谢谢。我很高兴在WiX文档中将其作为“如何引导”之一,即“基于缺少的注册表项阻止引导程序安装”我该怎么做才能实现这一点? - Pauli Price
听起来不错。要添加帮助,请针对wix38分支发送拉取请求,并对以下文件进行更改: src\chm\html 。代码是 wix.codeplex.com - Rob Mensching
请参阅codeplex上的pull请求。 - Pauli Price


答案:


根本问题是 RegistrySearch 在一个单独的 Fragment 永远不会被引用。因为什么都没有 Fragment 引用链接器“优化掉”的内容 Fragment 并且搜索不包含在您的 Bundle

除此之外:你可以争辩说,有一个事实,即在搜索中提到的变量 Condition 链接器应该能够确定搜索是必要的。但是,这并不适用于所有情况。

幸运的是,解决方案非常简单!你甚至必须从以下两种中选择一种:

  1. 移动 RegistrySearch 要素 Bundle 元件。
  2. 添加一个 RegistrySearchRef 中的元素 Bundle 元素来引用 RegistrySearch 在里面 Fragment。你还需要给予 RegistrySearch 和 Id 属性。

就个人而言,我喜欢选项二,我甚至可能会移动 Condition 进入 Fragment 以及将所有这些东西组合在一起。类似于:

<Bundle ...>
   <util:RegistrySearchRef Id='SearchForThirdParty' />

   ...

</Bundle>

<Fragment>
   <util:RegistrySearch
          Id='SearchForThirdParty' 
          Variable="ThirdPartyCOMLibraryInstalled" 
          Result="exists"
          Root="HKLM"
          Key="SOFTWARE\Classes\ThirdPartyId.Server\CLSID"/>

    <bal:Condition Message="ThirdParty Application COM Library Required. Please (re)install ThirdParty Application and ensure 'Windows API' and '.Net Components' are installed.">ThirdPartyCOMLibraryInstalled</bal:Condition>
  </Fragment>
</Wix>

应该这样做。


15
2018-04-19 16:28



这完全有效。谢谢。我很高兴在WiX文档中将其作为“如何引导”之一,即“基于缺少的注册表项阻止引导程序安装”我该怎么做才能实现这一点? - Pauli Price
听起来不错。要添加帮助,请针对wix38分支发送拉取请求,并对以下文件进行更改: src\chm\html 。代码是 wix.codeplex.com - Rob Mensching
请参阅codeplex上的pull请求。 - Pauli Price