Wix Burn vcredist

25

我有一个使用Visual Studio 2015开发的C++应用程序,同时还有一个Wix安装程序和一个Burn引导程序。以前版本的应用程序可以使用Visual Studio合并模块来安装必要的先决条件,但似乎在使用Visual Studio 2015时不再是一个选择(参见Redistributables for deploying C++ exe developed with Visual Studio 2015 on Windows 7)。

根据该链接中的建议,我们开始使用ExePackage在Burn中安装vcredist并将vital设置为“yes”。这基本上运作良好-我们已经有几个客户因为vcredist存在各种问题而导致安装失败。直到最近,这些都是应该导致安装失败的错误。

在过去的几天里,我们收到了多份报告,称我们的安装程序由于安装了更新版本的redistributable而失败:vcredist出现错误代码0x80070666,导致我们的引导程序失败。

我的问题是:

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

39
  1. 使用vcredist部署是一个合适的方法。

  2. 您可以使用FileSearch元素(Util扩展)搜索其中之一vcredist文件并检索其版本。但是,此方法由于burn内置变量SystemFolderSystem64Folder与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"/>

变量vc14x64Existsvc14x64Version可以在DetectCondition中使用,以确定是否安装了VC14的64位版本:

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

同样,VC14 32位版本的 DetectCondition 如下:

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

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

编辑1:作为另一种选择,您可以使用升级代码搜索来检测VC Redist的存在,如此处所述。

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

  • 到目前为止,我发现了三个VC14 redist文件版本:

    a) 14.0.23026 - 可从Microsoft链接here下载。

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

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

    尽管Visual Studio更新发布了更新版本的vcredist,但微软没有更新其网站上可下载的版本。

  • 您可以使用<ExitCode Value="1638" Behavior="success"/>告诉burn忽略已经安装的错误代码0x80070666。请注意: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已经安装则不会抛出错误。


    太棒了!为了澄清一下,我们迄今为止的非正式测试中,使用新版本的可再发行组件对编译在旧版本上的可执行文件没有遇到任何问题(即我们还没有升级到Visual Studio 2015更新1或2)。这是否有保证,或者我们需要在开始运送新的可再发行组件之前升级Visual Studio? - Runt8
    1
    在我的测试中,我没有发现在已经安装了较新版本的vcredist的计算机上运行使用旧版本vcredist构建的产品存在任何问题。然而,不能保证未来发布的vcredist版本不会破坏某些功能。我倾向于选择最新版本的vcredist,因为最新版本具有最新的错误和安全修复等更新。 - bradfordrg
    有没有注册表键可以读取以确定当前安装的版本,并将其用作“ExePackage”的“InstallCondition”? - tollgen
    <util:FileSearch Id="GetVC14X64Exists" Condition="VersionNT64" Variable="vc14x64Exists" Path="[SystemFolder]vcruntime140.dll" Result="exists"/> 对我总是返回 false(未找到 c:\windows\system32\vcruntime140.dll),即使已经安装了该软件包。但安装看起来仍然很好,可能是因为当它启动 VSRedist 安装程序时,它检测到已经安装。我注意到当我取消安装并检查日志时出现了这个问题。 目前,我只使用检测条件中的版本号。这个方法运行良好,并且安装速度更快。 - Daniel
    1
    很高兴了解到ExitCode属性,正是我需要的!但实际上有一个注册表键可以用来查找已安装的VCRedist版本:我在我的x64安装中使用<util:RegistrySearch Root="HKLM" Key="SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" Value="Major" Variable="Current_VCRedist_2015_x64_MajorVersion" />(以及类似的“minor”和“build”版本号)。 - Torbjörn Bergstedt
    显示剩余7条评论

    3
    要检测vcredist软件包的存在,您需要通过其UpgradeCode进行搜索。
    这将确保还能找到以后的版本。

    在wix burn bootstrapper中,使用UpgradeCode参数的util:ProductSearch,然后在DetectCondition中指定一个最小版本。

    有关完整详情,请参阅我给出的答案:https://dev59.com/kpTfa4cB1Zd3GeqPWtx2#35889484

    当前版本是通过烧录捆绑包进行部署的。 它们具有不同的捆绑包 ID。 目前无法使用 util:ProductSearch 进行查找。 - Stephen Reindl

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接