Wix 每个用户安装程序以检测 Visual C++ 2015 Redistributable [英] Wix per user installer to detect the Visual C++ 2015 Redistributable

查看:21
本文介绍了Wix 每个用户安装程序以检测 Visual C++ 2015 Redistributable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个 .msi 安装程序,它必须确定系统中是否存在 Visual C++ 2015 Redistributable,如果没有,则使用自定义消息中断安装.官方 Wix 文档指的是 VC++ 的实际安装,我不希望这样做,因为我的安装程序是每个用户",还有其他几个 stackoverflow 问题指的是捆绑包而不是 .msi http://wixtoolset.org/documentation/manual/v3/howtos/redistributables_and_install_checks/install_vcredist.html.
Wix Burn vcredist, WIX 检查是否安装了 VS2015 C++ 可再发行组件 , https://gist.github.com/nathancorvussolis/6852ba282647aeb0c5c00e742e28eb48

所以我想问题是,如何有效地检测每个用户安装程序中是否存在 Visual C++ 2015 Redistributable.

解决方案

最新支持的 Visual C++下载


运行时检测方法

我可以找到几种方法来检测 Visual C++ 运行时的存在.

  1. 注册表

  2. 文件存在与版本检查

    • 检查是否存在核心运行时文件
    • 请参阅下面的单独部分
  3. MSI API

    • 您可以通过查找产品 GUID 来检测是否安装了特定的 MSI
    • 可靠,但难以跟踪所有产品 GUID(不同版本)
    • 更新:您还可以使用如下所述的升级代码.它应该在发布和更新之间保持稳定(对于每个主要版本,也可能在主要版本之间).
  4. Fall-Over EXE?

    • 建议使用 EXE,具体取决于运行时
    • 启动它并失败意味着运行时不存在或损坏


好&不好 - 评估:选项 1 似乎容易受到攻击,因为部署运行时的合并模块变体可能不会写入这些密钥.选项 3 可能效果很好,但很难跟踪所有 GUID.Option 4 似乎已经失败,因为较新的运行时删除了某些注册表项.虽然现在已经修复,但它可能会重新出现.


文件版本存在/版本检查

我看的越多,我越开始认为您必须检查实际文件本身,并可能检查正确的文件版本.System32 文件夹(64 位版本)和 中的文件 vcruntime140.dllSysWOW64 文件夹(32 位版本)?查看文件列表在这里底部.

只是添加一个安全保存的链接.

测试 VBScript - 仅用于测试目的(脚本有时会被防病毒软件阻止):

设置 fso = CreateObject("Scripting.FileSystemObject")MsgBox fso.GetFileVersion("C:WindowsSystem32vcruntime140.dll")

您可以在 MSI 文件中使用 AppSearch 检测文件的存在和版本.


下面是我写的一些其他的东西,只是把它留在里面.


VCredist

似乎是 Visual C++ Redistributable Packages(VCRedist_x86.exeVCRedist_x64.exe) - 这是部署运行时的推荐方法 - 检查以下注册表项以确定实际安装的运行时版本:

<块引用>

HKLMSOFTWAREMicrosoftVisualStudio<版本>VCRuntimes

子键 x86x64 似乎都包含一个Installed";安装运行时时设置为 1 的值.我会假设 - 没有时间测试它 - 然后你可以检查:

  • HKLMSOFTWAREWOW6432NodeMicrosoftVisualStudio14.0VCRuntimesx64 Installed = 1
  • HKLMSOFTWAREWOW6432NodeMicrosoftVisualStudio14.0VCRuntimesx86 Installed = 1

合并模块:经过简单检查,这些值似乎不是由也可用于分发此运行时的合并模块写入的.我现在没有时间或方法来正确检查.

令人惊讶的是,2015 版和 2017 版运行时都写入了 14.0 密钥 - 因为它们是二进制兼容的. 如果安装了 2017 版,则 VCRedist 可执行文件将返回错误,因为不需要安装.确实很奇怪.但为了您的目的,这应该是无关紧要的.来源.


MSI API - 检索产品代码


<块引用>

更新:installer.ProductState - 正常安装状态是5:

我忘记了 ProductState 属性 写下面的时候.您可以使用两行代码检查已安装的产品,如果您有实际的产品代码:

Dim 安装程序:Set installer = CreateObject("WindowsInstaller.Installer")MsgBox installer.ProductState("{00000000-0000-0000-0000-000000000001}")

这里还有另一种方法:MSDN:如何以编程方式检查是否存在 Windows Installer基于产品的产品代码.

<块引用>

提示:我不会使用这种方法,因为产品更新时产品代码会频繁更改.因此我更喜欢检查核心运行时文件的文件版本.这似乎更未来可靠(前提是版本解析正确完成并且可靠——不要自己动手).


样机:

公共安装程序设置安装程序 = CreateObject("WindowsInstaller.Installer")' 没有 2015 GUIDVC2015 = CheckForProductCode("{00000000-0000-0000-0000-000000000000}")VC2017 = CheckForProductCode("{C77195A4-CEB8-38EE-BDD6-C46CB459EF6E}")MsgBox "VC2015:"&CStr(VC2015) &vbCrLf &VC2017:"&CStr(VC2017)函数 CheckForProductCode(productcode)CheckForProductCode = False对于 installer.ProductsEx("", "", 7) 中的每个产品如果(LCase(productcode) = LCase(product.ProductCode)) 那么CheckForProductCode = True退出万一下一个结束功能

更新基于 Zett42 的建议列举共享相同升级代码的产品:

Set installer = CreateObject("WindowsInstaller.Installer")' 枚举与Microsoft Visual C++ 2008 Redistributable - x86 9.0.30729.4148"相关的所有产品' {AA783A14-A7A3-3D33-95F0-9A351D530011} 是升级代码设置升级 = installer.RelatedProducts("{AA783A14-A7A3-3D33-95F0-9A351D530011}")对于每个 u In 升级MsgBox u, vbOKOnly, 产品代码:"下一个


部署 Visual Studio C++ 运行时

除了检测之外,还有多种分发 Visual Studio C++ 运行时的方法:

  1. 静态链接
  2. Visual C++ 可再发行包
    • VCRedist_x86.exeVCRedist_x64.exeVCRedist_arm.exe
    • Program Files(x86)Microsoft Visual Studio2017editionVCRedistMSVClib-version
  3. 可再发行的合并模块(.msm 文件)
  4. 本地应用程序文件夹
    • 将 DLL 复制到本地应用程序文件夹
    • 出于维修原因(更新、安全修复),不推荐使用


安全保存链接:


旧答案

有这个旧帖子.我不太喜欢直接读取注册表,让我看看是否能找到更可靠的方法,但也许同时看看:检测是否安装了 Visual C++ Redistributable for Visual Studio 2012

还有一个链接,如何找到已安装产品的 Windows Installer 产品代码:如何找到已安装 MSI 设置的产品 G​​UID?

I am creating an .msi installer which has to determine whether the Visual C++ 2015 Redistributable is present in the system and if not then interrupt the installation with custom message. The official Wix documentation refers to the actual installation of the VC++ which I do not wish to do as my installer is "per user" , There are couple of others stackoverflow questions which refer to the bundle rather than the .msi http://wixtoolset.org/documentation/manual/v3/howtos/redistributables_and_install_checks/install_vcredist.html.
Wix Burn vcredist, WIX check if VS2015 C++ redistributable is installed , https://gist.github.com/nathancorvussolis/6852ba282647aeb0c5c00e742e28eb48

So I guess the question is, how to efficiently detect the presense of Visual C++ 2015 Redistributable in the per user installer.

解决方案

The latest supported Visual C++ downloads


Runtime Detection Approaches

I can find a few ways to detect the presence of the Visual C++ Runtime.

  1. Registry

  2. File Presence & Version Check

    • Check for presence of core runtime files
    • See separate section below
  3. MSI API

    • You can detect whether a specific MSI is installed by looking up the product GUID
    • Reliable, but hard to keep track of all product GUIDs (different versions)
    • UPDATE: You can also use the upgrade code as described below. It should remain stable across releases and updates (for each major version and potentially between major versions as well).
  4. Fall-Over EXE?

    • Suggestions are seen to use an EXE depending on the runtime
    • Launching it and failing means the runtime is not there or broken


Good & Bad - Evaluation: Option 1 seems to be vulnerable since the merge module variant of deploying the runtime might not write these keys. Option 3 might work well, but it is hard to keep track of all GUIDs. Option 4 seems to already have failed based on the newer runtimes removing certain registry keys. Though fixed now, this could resurface.


File Version Presence / Version Check

The more I look at this, the more I start to think that you have to check for the actual files themselves, and potentially for the right file version. The file vcruntime140.dll in the System32 folder (64-bit version) and SysWOW64 folder (32-bit version)? See files list towards bottom here.

Just adding a link for safe-keeping.

A test VBScript - for test purposes only (scripts are sometimes blocked by anti-virus):

Set fso = CreateObject("Scripting.FileSystemObject")
MsgBox fso.GetFileVersion("C:WindowsSystem32vcruntime140.dll")

You can detect file presence and version using AppSearch in an MSI file.


Below are some other stuff I wrote up, just leaving it in.


VCRedist

It seems the Visual C++ Redistributable Packages (VCRedist_x86.exe, VCRedist_x64.exe) - which is the recommende way to deploy the runtime - checks the following registry key to determine what versions of the runtime is actually installed:

HKLMSOFTWAREMicrosoftVisualStudio<version>VCRuntimes

The sub-keys x86 and x64 seem to all contain an "Installed" value that is set to 1 when the runtime is installed. I would assume - without having had time to test it all - that you then can check:

  • HKLMSOFTWAREWOW6432NodeMicrosoftVisualStudio14.0VCRuntimesx64 Installed = 1
  • HKLMSOFTWAREWOW6432NodeMicrosoftVisualStudio14.0VCRuntimesx86 Installed = 1

Merge Module: After a brief check, it looks like these values are not written by the merge modules that can also be used to distribute this runtime. I do not have the time or means to check this properly now.

Astonishingly both version 2015 and version 2017 of the runtime write to the 14.0 key - since they are binary compatible. If the 2017 version is installed, then the VCRedist executable will return an error since no install is needed. Weird indeed. But for your purpose that should be besides the point. Source.


MSI API - Retrieve Product Codes


UPDATE: installer.ProductState - normal installed state is 5:

I forgot about the ProductState property when writing the below. You can check for an installed product with two lines of code if you have the actual product code:

Dim installer : Set installer = CreateObject("WindowsInstaller.Installer")
MsgBox installer.ProductState("{00000000-0000-0000-0000-000000000001}")

Here is even one more way to do it: MSDN: How to programmatically check for the presence of a Windows Installer-based product by using its product code.

Tip: I wouldn't use this approach seeing as the product code changes frequently when products are updated. Hence I like better to check for file versions of core-runtime files. This seems more reliable for the future (provided version parsing is done correctly and reliably - don't roll your own).


Mockup:

Public installer
Set installer = CreateObject("WindowsInstaller.Installer")

' Don't have the 2015 GUID
VC2015 = CheckForProductCode("{00000000-0000-0000-0000-000000000000}")
VC2017 = CheckForProductCode("{C77195A4-CEB8-38EE-BDD6-C46CB459EF6E}")
   
MsgBox "VC2015: " & CStr(VC2015) & vbCrLf & "VC2017: " &  CStr(VC2017)

Function CheckForProductCode(productcode)

   CheckForProductCode = False

    For Each product In installer.ProductsEx("", "", 7)   
        If(LCase(productcode) = LCase(product.ProductCode)) Then
            CheckForProductCode = True
            Exit For
        End If
    Next

End Function

Update based on Zett42's suggestion to enumerate products sharing the same upgrade code:

Set installer = CreateObject("WindowsInstaller.Installer")

' Enumerate all products related to "Microsoft Visual C++ 2008 Redistributable - x86 9.0.30729.4148"

' {AA783A14-A7A3-3D33-95F0-9A351D530011} is the upgrade code
Set upgrades = installer.RelatedProducts("{AA783A14-A7A3-3D33-95F0-9A351D530011}")
For Each u In upgrades
   MsgBox u, vbOKOnly, "Product Code: "
Next


Deploying The Visual Studio C++ Runtime

Beyond detection, there are several approaches for distributing the Visual Studio C++ Runtime:

  1. Static Linking
  2. Visual C++ Redistributable Packages
    • VCRedist_x86.exe, VCRedist_x64.exe, or VCRedist_arm.exe
    • Program Files(x86)Microsoft Visual Studio2017editionVCRedistMSVClib-version
  3. Redistributable Merge Modules (.msm files)
  4. Local Application Folder
    • Copy DLLs to the local application folder
    • Not recommended for servicing reasons (updates, security fixes)


Links For Safe Keeping:


Old Answer

There is this old post. I am not too fond of direct registry reads, let me see if I can find a more reliable way, but maybe have a look in the mean time: Detect if Visual C++ Redistributable for Visual Studio 2012 is installed

Just one more link, how to find the Windows Installer product code of products that are installed: How can I find the product GUID of an installed MSI setup?

这篇关于Wix 每个用户安装程序以检测 Visual C++ 2015 Redistributable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆