Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
619 views
in Technique[技术] by (71.8m points)

installation - WiX Bundle bal:condition - util:RegistrySearch variable always false

I want my install to fail if a third-party software element is not installed. I added a Fragment with a util:RegistrySearch and a bal:Condition to the Bundle, but I can't get it to work. ThirdPartyCOMLibraryInstalled never evaluates to true. I've confirmed that the key exists, and the value I use for Key is correct - I copy/pasted the name from the selected key in regedit. There aren't any errors in the log.

I'm building the installer with WiXTools 3.7 in Visual Studio 2012 on Windows 7 64-bit and testing on both Windows XP SP3 and Windows 7 64-bit.

Searching online for other examples for util:RegistrySearch I ran across the following alternative forms for the condition test expression.

  1. ThirdPartyCOMLibraryInstalled = 0 - always False
  2. ThirdPartyCOMLibraryInstalled <> 1 - always True

Here is the Bundle code:

<?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 SystemsMy_Application"/>
        <BootstrapperApplicationRef
            Id="WixStandardBootstrapperApplication.HyperlinkLicense" >

            <bal:WixStandardBootstrapperApplication
                ThemeFile="ResourcesHyperlinkTheme.xml"
                LaunchTarget="[InstallFolder]My_Application.exe"
                LocalizationFile="ResourcesHyperlinkTheme.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="SOFTWAREClassesThirdPartyId.ServerCLSID"/>
    </Fragment>
</Wix>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The root issue is that the RegistrySearch is in a separate Fragment that never gets referenced. Because nothing in the Fragment gets referenced the linker "optimizes away" the contents of the Fragment and the search is not included in your Bundle.

Aside: you could argue that the fact that there is a reference to the variable mentioned in the search in the Condition that the linker should be able to figure out that the search is necessary. However, that doesn't work out in all cases.

Fortunately, the solution is quite simple! You even have to choose from one of two:

  1. Move the RegistrySearch element to the Bundle element.
  2. Add a RegistrySearchRef element in the Bundle element to reference the RegistrySearch in the Fragment. You will also need to give the RegistrySearch and Id attribute.

Personally, I like option two and I would probably even move the Condition into the Fragment as well to group all that stuff together. Something akin to:

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

   ...

</Bundle>

<Fragment>
   <util:RegistrySearch
          Id='SearchForThirdParty' 
          Variable="ThirdPartyCOMLibraryInstalled" 
          Result="exists"
          Root="HKLM"
          Key="SOFTWAREClassesThirdPartyId.ServerCLSID"/>

    <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>

That should do it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...