24

我有一个使用 Visual Studio 2015 开发的 c++ 应用程序,以及一个 Wix 安装程序和一个 Burn 引导程序。该应用程序的早期版本能够使用 Visual Studio 合并模块来安装必要的先决条件,但在使用 Visual Studio 2015 时这似乎不是一个选项(请参阅Redistributables 以在 Windows 7 上部署使用 Visual Studio 2015 开发的 C++ exe)。

按照该链接中的建议,我们已经开始使用带有 vital="yes" 的 ExePackage 安装带有 Burn 的 vcredist。这通常效果很好 - 我们有几个客户由于 vcredist 的各种问题而安装失败。直到最近,这些都是会导致安装失败的错误。

在过去的几天里,我们收到了几份由于安装了更新版本的可再发行组件而导致安装程序失败的报告:vcredist 失败,错误代码为 0x80070666,这导致我们的引导程序失败。

我的问题是:

  1. 部署 vcredist 是“正确”的方法吗?(假设我们需要一个 exe 安装程序)
  2. 我们如何知道安装了哪个版本的可再发行组件(不一定在引导程序中,这些信息是否以用户可读的形式存储在某处)?
  3. 是否有我们应该分发的更新版本的可再发行产品?(目前使用 14.0.23026)这是基于用于编译的 Visual Studio 版本还是我们应该始终分发最新版本?(当前 VS 版本 14.0.23107.0)
  4. 作为最后的手段,是否可以检测从 vcredist 返回的错误代码并允许该值确定安装是继续还是失败?
4

2 回答 2

36
  1. 部署 vcredist 是一种合适的方法。

  2. 您可以使用FileSearch 元素(实用程序扩展)来搜索 vcredist 文件之一并检索其版本。然而,这种方法由于内置变量的刻录而变得复杂,SystemFolder并且System64Folder相对于 Windows Installer 中的类似变量是相反的。搜索 VC14 的示例:

    <!-- Detect existing version of VC ++ 2015 x64 libraries -->
    <util:FileSearch Id="GetVC14X64Exists" Condition="VersionNT64" Variable="vc14x64Exists" Path="[SystemFolder]vcruntime140.dll" Result="exists"/>
    <util:FileSearch Id="GetVC14X64Version" Condition="VersionNT64" Variable="vc14x64Version" Path="[SystemFolder]vcruntime140.dll" Result="version"/>
    
    <!-- Detect existing version of VC ++ 2015 x86 libraries -->
    <util:FileSearch Id="GetVC14X86onX64Exists" Condition="VersionNT64" Variable="vc14x86Exists" Path="[System64Folder]vcruntime140.dll" Result="exists"/>
    <util:FileSearch Id="GetVC14X86onX64Version" Condition="VersionNT64" Variable="vc14x86Version" Path="[System64Folder]vcruntime140.dll" Result="version"/>
    <util:FileSearch Id="GetVC14X86onX86Exists" Condition="NOT VersionNT64" Variable="vc14x86Exists" Path="[SystemFolder]vcruntime140.dll" Result="exists"/>
    <util:FileSearch Id="GetVC14X86onX86Version" Condition="NOT VersionNT64" Variable="vc14x86Version" Path="[SystemFolder]vcruntime140.dll" Result="version"/>
    

    vc14x64Exists然后vc14x64Version可以在 a 中使用这些变量DetectCondition来确定是否安装了 64 位版本的 VC14:

    DetectCondition="vc14x64Exists AND vc14x64Version &gt;= v14.0.nnnnn"
    

    同样,DetectCondition对于 VC14 的 32 位版本是:

    DetectCondition="vc14x86Exists AND vc14x86Version &gt;= v14.0.nnnnn"
    

    注意:在这两种情况下,您都需要替换nnnnn为安装程序中包含的 vcredist 的内部版本号。

    编辑 1:作为替代方案,您可以使用此处概述的升级代码搜索来检测 VC Redist 的存在。

    编辑 2:在我编写的安装程序中,我通常不会尝试检测 VC Redist 的存在。相反,我让 VC Redist 安装程序运行,让它自己决定是安装、升级还是什么都不做。

  3. 迄今为止,我已经找到了三个版本的 VC14 redist 文件:

    a) 14.0.23026 - 可从此处的 Microsoft 链接下载

    b) 14.0.23506 - 随Visual Studio 2015 Update 1提供。

    c) 14.0.23918 - 随Visual Studio 2015 Update 2提供。

    尽管更新版本的 vcredist 已随 Visual Studio 更新一起发布,但 Microsoft 尚未更新可从其网站下载的版本。

  4. 您可以告诉 Burn 忽略已安装的错误代码 0x80070666,使用<ExitCode Value="1638" Behavior="success"/>. 请注意,1638 = 0x666。例如:

    <!-- Microsoft Visual C++ 2015 x86 libraries -->
    <PackageGroup Id="VC14RedistX86">
      <ExePackage
         Cache="no"
         Compressed="yes"
         PerMachine="yes"
         Permanent="yes"
         Vital="yes"
         Name="Redist\vcredist14_x86.exe"
         SourceFile="$(var.RedistPath)\VC14\vcredist_23918_x86.exe"
         InstallCommand="/install /quiet /norestart">
    
         <!-- -->
         <ExitCode Value="3010" Behavior="forceReboot"/>
    
         <!-- Ignore "Newer version installed" error -->
         <ExitCode Value="1638" Behavior="success"/>
      </ExePackage>
    </PackageGroup>
    

我最近遇到了一个类似的问题,我正在处理的产品安装程序因错误 0x80070666 而停止。问题是已经安装了较新版本的 vcredist。我最终使用的解决方案是:a) 包括最新版本的 vcredist (14.0.23918),b) 添加<ExitCode Value="1638" Behavior="success"/>指令以告诉 burn 如果已经安装了未来更新版本的 vcredist,则不要抛出错误。

于 2016-05-23T19:47:36.380 回答
3

要检测 vcredist 包的存在,您需要按其搜索UpgradeCode
这将确保也能找到更高版本。

在 wix 烧录引导程序util:ProductSearch中与UpgradeCode参数一起使用。然后在. _DetectCondition

有关详细信息,请参阅我的这个答案:https ://stackoverflow.com/a/35889484

于 2016-12-07T12:17:55.850 回答