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

标签 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. 将字符串变量“OLBitness”设置为值“x64”
  2. 条件“OLBitness=x64”的计算结果为 false
  3. 变量:OLBitness = x64

为什么将条件评估为 false 而值显然似乎是预期的?

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

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

我找到了带有 Result="exists"但没有带有 Result="value"的 RegistrySearches 示例。

感谢任何提示!

最佳答案

尝试

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”进行比较,这将强制进行字符串比较。

关于wix - 如何根据 Wix 包中的字符串比较编写 MsiPackage/InstallCondition?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36797522/

相关文章:

WiX Burn Bootstrapper 被趋势科技检测为病毒/恶意软件

wix - WiX中Burn/bootstrapper的命令行标志/选项的完整列表

c# - WiX 烧录 : how to change 'WixBundleManufacturer' in bootstrapper application?

windows - 如何使用 WiX 在 NetworkService 帐户下安装和启动 Windows 服务?

WiX 在 msi 中安装 C++ 可再发行组件

msbuild - 如何在 MSBuild 中使用团队构建属性?

clickonce - 嵌入 list 后无法签署 Bootstrap 可执行文件 (setup.exe)

wix - msiexec : Default to "do not close application" in silent mode

wix - MSI引用计数:两种产品安装相同的MSI

c# - 使用 Unity BootStrapper 和 Prsim 将参数传递给 Shell Viewmodel