每个用户安装程序使用Wix来检测Visual C ++ 2015可再发行组件 [英] Wix per user installer to detect the Visual C++ 2015 Redistributable

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

问题描述

我正在创建一个.msi安装程序,该安装程序必须确定系统中是否存在Visual C ++ 2015 Redistributable,如果没有,则使用自定义消息中断安装.正式的Wix文档指的是VC ++的实际安装,我不希望这样做,因为我的安装程序是按用户"的.还有其他一些stackoverflow问题,这些问题指的是捆绑软件,而不是.msi 修整刻录vcredist

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

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

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

推荐答案

运行时检测方法

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

  1. 注册表

  1. Registry

文件状态&版本检查

File Presence & Version Check

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

MSI API

MSI API

  • 您可以通过查找产品GUID来检测是否安装了特定的MSI
  • 可靠但难以跟踪所有产品GUID(不同版本)
  • 更新:您还可以按照以下说明使用升级代码.在各个发行版和更新中(对于每个主要版本,甚至可能在主要版本之间),它都应保持稳定.
  • 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).

Fall-over EXE?

Fall-Over EXE?

  • 建议根据运行时使用EXE
  • 启动它并失败意味着运行时不存在或损坏


Good&错误-评估 : Option 1 似乎很容易受到攻击,因为部署运行时的合并模块变体可能不会编写这些键. Option 3 可能效果很好,但是很难跟踪所有GUID.由于更新的运行时删除了某些注册表项,因此 Option 4 似乎已经失败.尽管现在已解决,但可能会重新出现.


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.

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

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.

  • How to detect the presence of the Visual C++ 2012 redistributable package?
  • Redistributing Visual C++ Files

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

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

Set fso = CreateObject("Scripting.FileSystemObject")
MsgBox fso.GetFileVersion("C:\Windows\System32\vcruntime140.dll")

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

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.

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

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:

HKLM\SOFTWARE\Microsoft\VisualStudio\<version>\VC\Runtimes\

子键 x86 x64 似乎都包含一个设置为 1 的"已安装"值. strong>在安装运行时时.我假设-没有时间测试所有内容-然后可以检查:

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:

  • HKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x64 Installed = 1
  • HKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86 Installed = 1
  • HKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x64 Installed = 1
  • HKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86 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.

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

  • Mailbag: How to detect the presence of the VC 8.0 runtime redistributable package
  • Updated VC 8.0 runtime redistributable packages are included in Visual Studio 2005 SP1
  • How can I find the product GUID of an installed MSI setup?

UPDATE : installer.ProductState -正常安装状态为 5 :

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

我忘记了 ProductState属性 编写以下内容时. 如果您有两行代码,则可以检查是否有已安装的产品 具有实际的产品代码:

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


部署Visual Studio C ++运行时

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


Deploying The Visual Studio C++ Runtime

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

  1. 静态链接
  2. Visual C ++可再发行组件包
    • VCRedist_x86.exe VCRedist_x64.exe VCRedist_arm.exe
    • Program Files(x86)\Microsoft Visual Studio\2017\edition\VC\Redist\MSVC\lib-version
  1. Static Linking
  2. Visual C++ Redistributable Packages
    • VCRedist_x86.exe, VCRedist_x64.exe, or VCRedist_arm.exe
    • Program Files(x86)\Microsoft Visual Studio\2017\edition\VC\Redist\MSVC\lib-version
查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆