如何确定现有应用的安装范围?

时间:2019-07-03 20:00:59

标签: wix windows-installer

我有一个基于WixUI_Advanced的安装程序,允许用户选择安装范围(按用户或计算机范围)。

升级时(已安装了较低版本的现有应用程序),我想隐藏安装范围屏幕并自动选择他们上次选择的安装范围。

如何知道以前的安装使用了什么安装范围?


修改

查看我的MSI日志,可以看到已找到我的现有安装:

// Existing user specific installation
FindRelatedProducts: Found application: {C5D3DCD0-4A97-4224-AF22-BDDEB357EEB7}
MSI (c) (C4:F0) [11:11:39:289]: PROPERTY CHANGE: Adding WIX_UPGRADE_DETECTED property. Its value is '{C5D3DCD0-4A97-4224-AF22-BDDEB357EEB7}'.
MSI (c) (C4:F0) [11:11:39:289]: PROPERTY CHANGE: Adding MIGRATE property. Its value is '{C5D3DCD0-4A97-4224-AF22-BDDEB357EEB7}'.

// Existing machine wide installation
MSI (c) (2C:4C) [11:03:19:258]: FindRelatedProducts: current install is per-user.  Related install for product '{C5D3DCD0-4A97-4224-AF22-BDDEB357EEB7}' is per-machine.  Skipping...

我可以看到WIX_UPGRADE_DETECTEDMIGRATE属性仅在现有安装的范围与当前安装匹配时才设置。也许我可以直接使用FindRelatedProducts

2 个答案:

答案 0 :(得分:1)

  

这不是一个完整的答案。我不得不添加为答案,因为   格式要求。


更新:看着这个,又没时间了。 This really is no answer at all, but just lobbing it to you in case it can help you research it yourself

注册表持久性 :我假设您已尝试将 ALLUSERS 和/或安装范围持久化到注册表中并阅读放回更新的MSI中?我没看那个。为此,您必须在程序包的第一个版本中执行此操作,然后再进行维护。

MSI API自动化 :这是一个小技巧,可以在包装盒上找到以前安装的产品(这实际上与MSI文件中的"FindRelatedProducts"类似, ):

内部MSI

Set upgrades = Session.installer.RelatedProducts("INSERT-UPGRADE-CODE")
For Each u In upgrades
    scope = Session.installer.ProductInfo(u,"AssignmentType")
    MsgBox CStr(scope)
Next

独立运行,直接运行脚本 (首先安装具有指定升级代码的MSI):

Set installer = CreateObject("WindowsInstaller.Installer")
Set upgrades = installer.RelatedProducts("INSERT-UPGRADE-CODE")

For Each u In upgrades
   MsgBox "Product Code: " & u & vbNewLine & "Installation Context: " & installer.ProductInfo(u,"AssignmentType")   
Next

MsgBox "Done"

我当时想在GUI序列中执行类似的操作,但是又用光了时间:

If scope = 1 Then
  Session.Property("ALLUSERS") = "1"
  Session.Property("MSIINSTALLPERUSER") = ""
  Session.Property("WixAppFolder") = "WixPerMachineFolder"
Else
  Session.Property("ALLUSERS") = "2"
  Session.Property("MSIINSTALLPERUSER") = "1"
  Session.Property("WixAppFolder") = "WixPerUserFolder"
End If

WiX片段

<Binary Id='Scope.vbs' SourceFile='Debugging Custom Actions\Scope.vbs' />
<CustomAction Id='Scope.vbs' VBScriptCall='' BinaryKey='Scope.vbs' Execute='immediate' Return='ignore'/>

<..>

<InstallUISequence>
  <Custom Action='Scope.vbs' Before='CostInitialize' />      
</InstallUISequence>

我本来要看这个的,但是没时间了。实际上,将在正在安装的新设置中设置 WIX_UPGRADE_DETECTED See this answer for more。您可以使用该属性来确定是隐藏还是显示按钮。我对此进行了简短的测试,并且可以正常工作,但是在WiX中实现它却更加困难。我认为您需要覆盖整个对话框。

在MSI表中,应该是这样的(Orca屏幕截图-MSI viewer tools):

Orca


添加更多链接:

答案 1 :(得分:0)

我最终检查了DisplayName与注册表中我们应用程序名称匹配的条目(受this answer启发):

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

然后,我抓取InstallLocation的内容以确定安装范围:

if (installLocation == string.Empty)
{
    // Installed before we introduced scope => never set install location
    return ExistingInstallation.MachineWide;
}
else if (installLocation.Contains(_programFilesPath))
{
    return ExistingInstallation.MachineWide;
}
else
{
    return ExistingInstallation.UserSpecific;
}