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

时间:2013-04-19 15:41:51

标签: installer wix registry wix3.6

如果未安装第三方软件元素,我希望我的安装失败。我向Fragment添加了util:RegistrySearch bal:ConditionBundle,但我无法让它工作。 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 - 永远是真的
  3. 以下是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>
    

1 个答案:

答案 0 :(得分:15)

根本问题是RegistrySearch位于一个永远不会被引用的单独Fragment中。由于Fragment中没有任何内容被引用,链接器会“优化”Fragment的内容,并且搜索不会包含在Bundle中。

  

除此之外:您可以争辩说,在Condition中搜索中提到的变量的引用可以使链接器能够确定搜索是必要的。但是,这并不适用于所有情况。

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

  1. RegistrySearch元素移至Bundle元素。
  2. RegistrySearchRef元素中添加Bundle元素,以引用RegistrySearch中的Fragment。您还需要提供RegistrySearchId属性。
  3. 就个人而言,我喜欢选项二,我甚至可能会将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>
    

    应该这样做。