"每个用户的"安装模式似乎有一些魔力。
我们的应用程序有autoupdater,它不使用insaller,我想更新"添加/删除程序"中显示的应用程序版本。窗口。设置信息(以及版本)实际存储在
中,我感到非常惊讶 HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{ProductId}
和
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\{SId}\Products\{ProductId}
所以我的问题是:安装程序如何设置写入而不请求提升?为什么每个用户安装在HKLM注册,特别是第一次入口,看起来根本不与任何特定用户相关?
其他结果但更实际的问题是如何从代码更新它(当然没有提升)?
答案 0 :(得分:1)
Windows可以写入该卸载位置,因为它是Windows。安全限制适用于您执行的操作,而不适用于Windows。毕竟它是操作系统,可以做它所需要的。如果非高架安装无法在“程序和功能”中创建条目,那将会很奇怪。这些注册表项实际上并不在MSI文件中。
每个用户不是严格意义上的问题。如果需要,可以提升每用户安装,尽管常见的约定是每个用户安装都没有提升。如果您的更新程序写入卸载密钥,则需要提升。
附注:如果您的autoupdater正在更新或替换Windows Installer安装的文件,那么您将违反规则。只能使用基于MSI的解决方案进行更新。问题是Windows知道(例如)您安装的每个版本化文件的文件版本。如果用户进行了修复(或者由于某种原因发生了修复),那么您可能会发现Windows希望将文件还原到最初安装的版本。同样,如果您进行补丁或主要升级,那么Windows不知道如果磁盘上的版本与注册版本不匹配,是否需要更新文件,因此可能会要求原始MSI文件恢复它们。
答案 1 :(得分:1)
Windows Installer在多个上下文中运行。有调用它的上下文(通常是受限用户,或者至少是Administrator组中用户的非管理员变体)和服务上下文。后者几乎可以完全访问该机器,但在冒充原始调用者的同时完成了大部分工作。自定义和内置操作可以访问服务上下文(如果由UAC或早期广告允许),并且服务可以始终使用它。
这就是它如何获取访问权限。但为什么会使用此访问权来存储有关HKLM产品的信息?虽然您可能熟悉SharedDllRefCount,但它仅用于与其他解决方案的互操作性。 Windows Installer会自行跟踪类似或扩展的信息,并且需要访问它管理的所有安装的所有实例,即使它们是每个用户且该用户未登录。当用户未登录时,他们的HKCU密钥无法可靠访问,因此它不是Windows Installer使用的可行位置。因此它使用HKLM。
您可能还想知道为什么它必须能够访问每用户安装的数据。简而言之,因为它无法判断安装是否真的是每个用户。特别是在Windows 7和MSIINSTALLPERUSER
之前,但即使是现在也无法轻易确定安装是否可以写入共享计算机位置。所以我猜他们甚至都没有尝试确定这一点。毕竟,当简单的方法足够时,为什么要实现一个困难或脆弱的功能呢?
那么你如何更新它?通过安装更新的.msi文件并让Windows Installer服务为您更新它;这些注册表项是Microsoft允许随时更改的实现详细信息。您只能通过Msi * API调用(例如MsiEnumProductsEx或MsiConfigureProductEx)来阅读或编写它们。 (不可否认,将后者称为API来编写这些值有点延伸,但它是为数不多的有效方法之一。)即使数据存储在HKCU中,这部分答案也不会有任何不同。