如何根据Wix包中的字符串比较编写MsiPackage / InstallCondition?

时间:2016-04-22 15:13:55

标签: wix bootstrapper

在我的WiX Bootstrapper应用程序中,我想根据Outlook Bitness安装32位或64位MsiPackage。因此,我搜索注册表值(可以是x64x86),将其读入变量并将每个MsiPackage的InstallCondition设置为变量与适当值的字符串比较。

结果出乎意料。字符串比较显然不起作用。

我的Bundle.wxs看起来像这样:

<Wix ...>
<Bundle ... >
  <util:RegistrySearchRef Id="VSTORuntimeTest" />
  <util:RegistrySearchRef Id="VSTORuntimeVersionV4R" />
  <util:RegistrySearchRef Id="VSTORuntimeVersionV4" />

  <util:RegistrySearchRef Id="Outlook14Installed"/>
  <util:RegistrySearchRef Id="Outlook15Installed"/>
  <util:RegistrySearchRef Id="Outlook16Installed"/>
  <util:RegistrySearchRef Id="Outlook14Bitness"/>
  <util:RegistrySearchRef Id="Outlook15Bitness"/>
  <util:RegistrySearchRef Id="Outlook16Bitness"/>

  <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
    <bal:WixStandardBootstrapperApplication ... />
  </BootstrapperApplicationRef>
  <Variable Name="InstallSubFolder"
          Type="string"
          Value="$(var.CompanyFolderName)\$(var.ProductFolderName)" />

  <Chain>
    <PackageGroupRef Id="NetFx40Web"/>

    <ExePackage Id="VSTORuntime" SourceFile="$(var.SolutionDir)\WiX\vstor_redist.exe" Permanent="yes" Vital="yes" Cache="no" Compressed="no"
        DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=158917"
        PerMachine="yes"
        InstallCommand="/q /norestart"
        DetectCondition="VSTORFeature"
        InstallCondition="NOT VSTORFeature OR NOT (VSTORVersionV4R >=v10.0.40303) OR NOT (VSTORVersionV4 >=v10.0.21022)" />

    <MsiPackage
      Id="OLAddin64bit"
      Vital="yes"
      Name="$(var.ProductName) 64 bit"
      SourceFile="$(var.Setup_64bit_WiX.TargetPath)"
      InstallCondition="OLBitness = x64">
      <MsiProperty Name="INSTALLLOCATION" Value="[ProgramFiles64Folder][InstallSubFolder]"/>
    </MsiPackage>

    <MsiPackage
      Id="OLAddin32bit"
      Vital="yes"
      Name="$(var.ProductName) 32 bit"
      SourceFile="$(var.Setup_32bit_WiX.TargetPath)"
      InstallCondition="NOT (OLBitness = x64)">
      <MsiProperty Name="INSTALLLOCATION" Value="[ProgramFilesFolder][InstallSubFolder]"/>
    </MsiPackage>
  </Chain>
</Bundle>

<Fragment>
  <util:RegistrySearch Id="VSTORuntimeTest" Root="HKLM" Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4R\" Value="VSTORFeature_CLR40" Variable="VSTORFeature"/>
  <util:RegistrySearch Id="VSTORuntimeVersionV4R" Root="HKLM" Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4R\" Value="Version" Variable="VSTORVersionV4R"/>
  <util:RegistrySearch Id="VSTORuntimeVersionV4" Root="HKLM" Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4\" Value="Version" Variable="VSTORVersionV4"/>

  <util:RegistrySearch Id="Outlook14Installed" Root="HKLM" Key="SOFTWARE\Microsoft\Office\14.0\Outlook\InstallRoot\"                            Variable="Outlook14Installed"  Result="exists" Win64="yes"/>
  <util:RegistrySearch Id="Outlook15Installed" After="Outlook14Installed" Root="HKLM" Key="SOFTWARE\Microsoft\Office\15.0\Outlook\InstallRoot\" Variable="Outlook15Installed"  Result="exists" Win64="yes" />
  <util:RegistrySearch Id="Outlook16Installed" After="Outlook15Installed" Root="HKLM" Key="SOFTWARE\Microsoft\Office\16.0\Outlook\InstallRoot\" Variable="Outlook16Installed"  Result="exists" Win64="yes" />

  <util:RegistrySearch Id="Outlook14Bitness" Condition="Outlook14Installed" Variable="OLBitness" After="Outlook16Installed" Root="HKLM" Key="SOFTWARE\Microsoft\Office\15.0\Outlook\" Value="Bitness" Win64="yes" />
  <util:RegistrySearch Id="Outlook15Bitness" Condition="Outlook15Installed" Variable="OLBitness" After="Outlook16Installed" Root="HKLM" Key="SOFTWARE\Microsoft\Office\15.0\Outlook\" Value="Bitness" Win64="yes" />
  <util:RegistrySearch Id="Outlook16Bitness" Condition="Outlook16Installed" Variable="OLBitness" After="Outlook16Installed" Root="HKLM" Key="SOFTWARE\Microsoft\Office\16.0\Outlook\" Value="Bitness" Win64="yes" />

  <bal:Condition
    Message="Outlook 2010 or newer required.">
    Outlook14Installed Or Outlook15Installed or Outlook16Installed
  </bal:Condition>
</Fragment>

</Wix>

安装程序现在写入以下日志:

[5FBC:FE84][2016-04-22T16:30:05]i001: Burn v3.10.1.2213, Windows v6.3 (Build 9600: Service Pack 0), path: Setup.exe
[5FBC:FE84][2016-04-22T16:30:05]i000: Initializing string variable 'InstallSubFolder' to value 'foo'
[5FBC:FE84][2016-04-22T16:30:05]i009: Command Line: ''
...
[5FBC:FE84][2016-04-22T16:30:05]i100: Detect begin, 4 packages
[5FBC:FE84][2016-04-22T16:30:05]i000: Setting string variable 'NETFRAMEWORK40' to value '1'
[5FBC:FE84][2016-04-22T16:30:05]i000: Registry key not found. Key = 'SOFTWARE\Microsoft\Office\14.0\Outlook\InstallRoot\'
[5FBC:FE84][2016-04-22T16:30:05]i000: Setting numeric variable 'Outlook14Installed' to value 0
[5FBC:FE84][2016-04-22T16:30:05]i000: Registry key not found. Key = 'SOFTWARE\Microsoft\Office\15.0\Outlook\InstallRoot\'
[5FBC:FE84][2016-04-22T16:30:05]i000: Setting numeric variable 'Outlook15Installed' to value 0
[5FBC:FE84][2016-04-22T16:30:05]i000: Setting numeric variable 'Outlook16Installed' to value 1
[5FBC:FE84][2016-04-22T16:30:05]i052: Condition 'Outlook14Installed' evaluates to false.
[5FBC:FE84][2016-04-22T16:30:05]i052: Condition 'Outlook15Installed' evaluates to false.
[5FBC:FE84][2016-04-22T16:30:05]i052: Condition 'Outlook16Installed' evaluates to true.
[5FBC:FE84][2016-04-22T16:30:05]i000: Setting string variable 'OLBitness' to value 'x64'
[5FBC:FE84][2016-04-22T16:30:05]i000: Setting string variable 'VSTORFeature' to value '1'
[5FBC:FE84][2016-04-22T16:30:05]i000: Setting string variable 'VSTORVersionV4' to value '10.0.60301'
[5FBC:FE84][2016-04-22T16:30:05]i000: Setting string variable 'VSTORVersionV4R' to value '10.0.50903'
[5FBC:FE84][2016-04-22T16:30:05]i052: Condition 'NETFRAMEWORK40' evaluates to true.
[5FBC:FE84][2016-04-22T16:30:05]i052: Condition 'VSTORFeature' evaluates to true.
[5FBC:FE84][2016-04-22T16:30:05]i101: Detected package: NetFx40Web, state: Present, cached: None
[5FBC:FE84][2016-04-22T16:30:05]i101: Detected package: VSTORuntime, state: Present, cached: None
[5FBC:FE84][2016-04-22T16:30:05]i101: Detected package: Addin64bit, state: Absent, cached: None
[5FBC:FE84][2016-04-22T16:30:05]i101: Detected package: Addin32bit, state: Absent, cached: None
[5FBC:FE84][2016-04-22T16:30:05]i052: Condition 'Outlook14Installed Or Outlook15Installed or Outlook16Installed' evaluates to true.
[5FBC:FE84][2016-04-22T16:30:05]i199: Detect complete, result: 0x0
[5FBC:10EE4][2016-04-22T16:30:07]i000: Setting numeric variable 'EulaAcceptCheckbox' to value 1
[5FBC:FE84][2016-04-22T16:30:07]i200: Plan begin, 4 packages, action: Install
[5FBC:FE84][2016-04-22T16:30:07]w321: Skipping dependency registration on package with no dependency providers: NetFx40Web
[5FBC:FE84][2016-04-22T16:30:07]i052: Condition 'NOT VSTORFeature OR NOT (VSTORVersionV4R >=v10.0.40303) OR NOT (VSTORVersionV4 >=v10.0.21022)' evaluates to false.
[5FBC:FE84][2016-04-22T16:30:07]w321: Skipping dependency registration on package with no dependency providers: VSTORuntime
[5FBC:FE84][2016-04-22T16:30:07]i052: Condition 'OLBitness=x64' evaluates to false.
[5FBC:FE84][2016-04-22T16:30:07]i052: Condition 'NOT (OLBitness=x64)' evaluates to true.
[5FBC:FE84][2016-04-22T16:30:07]i000: Setting string variable 'WixBundleRollbackLog_Addin32bit' to value 'foo.log'
[5FBC:FE84][2016-04-22T16:30:07]i000: Setting string variable 'WixBundleLog_OLPlannerAddin32bit' to value 'foo.log'
[5FBC:FE84][2016-04-22T16:30:07]i201: Planned package: NetFx40Web, state: Present, default requested: Present, ba requested: Present, execute: None, rollback: None, cache: No, uncache: No, dependency: None
[5FBC:FE84][2016-04-22T16:30:07]i201: Planned package: VSTORuntime, state: Present, default requested: Absent, ba requested: Absent, execute: None, rollback: None, cache: No, uncache: No, dependency: None
[5FBC:FE84][2016-04-22T16:30:07]i201: Planned package: Addin64bit, state: Absent, default requested: Absent, ba requested: Absent, execute: None, rollback: None, cache: No, uncache: No, dependency: None
[5FBC:FE84][2016-04-22T16:30:07]i201: Planned package: Addin32bit, state: Absent, default requested: Present, ba requested: Present, execute: Install, rollback: Uninstall, cache: Yes, uncache: No, dependency: Register
[5FBC:FE84][2016-04-22T16:30:07]i299: Plan complete, result: 0x0
[5FBC:FE84][2016-04-22T16:30:07]i300: Apply begin
[5FBC:FE84][2016-04-22T16:30:07]i010: Launching elevated engine process.
...
[5FBC:FE84][2016-04-22T16:30:15]i399: Apply complete, result: 0x80070642, restart: None, ba requested restart:  No
[5FBC:FE84][2016-04-22T16:30:16]i500: Shutting down, exit code: 0x642
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: EulaAcceptCheckbox = 1
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: InstallSubFolder = foo
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: NETFRAMEWORK40 = 1
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: OLBitness = x64
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: Outlook14Installed = 0
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: Outlook15Installed = 0
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: Outlook16Installed = 1
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: VSTORFeature = 1
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: VSTORVersionV4 = 10.0.60301
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: VSTORVersionV4R = 10.0.50903
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: WixBundleAction = 5
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: WixBundleElevated = 0
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: WixBundleFileVersion = 1.0.0.0
[5FBC:FE84][2016-04-22T16:30:16]i410: Variable: WixBundleInstalled = 0
...
[5FBC:FE84][2016-04-22T16:30:16]i007: Exit code: 0x642, restarting: No

它声明:

  1. 设置字符串变量&#39; OLBitness&#39;重视&#39; x64&#39;
  2. 条件&#39; OLBitness = x64&#39;评估为假
  3. 变量:OLBitness = x64
  4. 为什么将条件评估为false,而值显然似乎是预期值?

    如何编写InstallCondition以测试字符串是否相等?

    我可以使用属性吗?如果可以,我该怎么做?

    我找到了RegistrySearches的示例,结果为=&#34;存在&#34;但不是结果=&#34;值&#34;。

    感谢任何提示!

1 个答案:

答案 0 :(得分:1)

尝试

InstallCondition="OLBitness ~= &quot;x64&quot;"

InstallCondition="NOT (OLBitness ~= &quot;x64&quot;)"

OLBitness变量是一个“字符串”变量,我认为x64可能会被解析为以十六进制表示的int或其他东西?然后,当它试图将字符串转换为int时,它会非常错误地转换它,因此它们永远不会匹配。

您可以对此进行调试,但设置需要一段时间。当我试图比较版本时,我不得不这样做。使用注册表搜索时,变量类型始终为字符串。来自wix源的引擎vcproj中的condition.cpp足够聪明,可以尝试将字符串变量转换为另一种类型(数字,版本)然后进行比较。事实证明我只是错误地拼写了变量名......

无论如何,你也可以添加

<Variable Id="x64Bitness" Value="x64" Type="string" />

到你的Bundle,然后在安装条件下将它与x64Bitness而不是“x64”进行比较,这将强制进行字符串比较。