InstallShield - 防止注册表值在升级过程中被补丁覆盖?

InstallShield - Prevent registry values to be overwritten by patch during upgrade?

我正在 InstallShield MSI 项目上使用 InstallShield 2016,并尝试创建一个带有更新可执行文件的次要补丁包。一切正常,但注册表值在更新时更改为默认值。

我已经研究过更改 REINSTALLMODE 字符串,但它可能对将来使用注册表项系统的限制太大。我还读过使用 AppSearch 和 RegLocator 表将值读入 msi 属性。我不明白如何使用这些表格,所以这是一个我不太明白的解决方案。

我错过了什么?

谢谢。

The Essence: I wrote a lot and nothing made that much sense. Let me try to make it short instead: Don't write registry values that your application might change. Here is what I might do to be better set with application settings management in the future: 1) use a custom REINSTALLMODE to not overwrite any registry keys on this update, and then I would 2) modify the application to copy the HKCU registry keys to a new location and never touch them from then on by your setup. 3) You should also update your application to be able to write all HKCU keys for your application if they are missing - based on read-only template settings stored in HKLM - or you write them from internal defaults stored in the application.exe.

This way you need no HKCU settings written by your setup at all in the future - and no interference will occur for modified values. There are ways to enforce new values - if you need to (UPDATE October 2021: link broken, but resurrected from Wayback Machine).


下面的我也会留下。


真实世界:这个“overwrite registry settings on upgrade problem”在我的意见MSI 设计反模式。或者,我喜欢这样称呼它:an MSI Festivus Grievance(必须查看视频了解上下文)。

为了可靠地避免这个问题,我建议您考虑这个选项:

消除部署注册表设置Generally you should not write registry settings from your setup that are ever changed by your application .

  • HKLM keys:我在HKLM中写了只读设置来自设置,并允许通过 msiexec.exe 命令行覆盖它们。然后我在使用 AppSearch 自定义操作 或根本不使用升级时重新阅读它们,具体取决于对业务逻辑有意义的内容和用例。

  • HKCU keys:我希望从部署中删除所有 HKCU 密钥完全在较新的版本中,并通过应用程序本身写入默认注册表项 - 使用其启动顺序。 这基本上总能消除很多部署问题。您甚至可以将已写入注册表中只读位置的应用程序复制设置复制到其活动的“实时”配置单元。例如,您从 HKLM 中的只读注册表部分复制默认值。

这是我喜欢用来“屏蔽”我的应用程序免受与每个用户数据有关的部署干扰的通用方法——无论是 HKCU 中的注册表项还是基于用户配置文件的数据。对于某些应用程序,这是不可能的。例如那些没有带有启动序列的 exe 的。

但是等等,即使您可以使用这种方法并删除托管新 MSI 中的注册表项的组件,然后卸载并重新安装(在重大升级期间 - 您需要删除组件)您的包撕掉注册表项,除非您已将它们完全设置为永久。

我有时得出结论,我必须保留旧组件并复制新组件以写入新的注册表项或写入不同的注册表值名称以保存新值。


记住 属性 模式:尽管对于 WiX 而不是 Installshield,Rob Mensching's "Remember Property Pattern" 是一个教训如何使用应用搜索。 Installshield 中的概念相同。您在维护和升级场景中使用 AppSearch 回读属性 - 就此而言,全新安装。

Rob 很好地说明了这个“记住模式”的讽刺之处在于它将如何覆盖您在 msiexec.exe[ 上指定的任何新值=120=] 命令行,除非您采取措施避免此问题(或者您的方案允许忽略此特定问题 - 这很少是安全的)。请阅读文章以了解整个故事。


Installshield:在 installshield 中,您定义 AppSearch 条目 系统搜索视图。这里的对话框在很大程度上应该是不言自明的,因为您只需指定应该将设置文件中的哪些注册表项或条目读入您指定要读入的任何 属性 中。这些对话框是“向导”,因此您只需单击它们并创建 AppSearch。

注意!:一个非常常见的烦恼是忘记根据位数(32 位与 64 位)引用正确的注册表配置单元:

  • HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\Mozilla Firefox
  • HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Mozilla\Firefox

这可能会导致一些真正的和反复的混淆 - 至少在我的世界里。这是一个愚蠢的问题,我们都想避免它浪费我们一分钟的时间。

您可以实施 Rob 建议的自定义操作,以避免 AppSearch 清除来自命令行的 属性 值。或者我想您可以忽略是否不应从命令行设置相关属性?我想这是可能的。


Custom Action Approaches:我不喜欢这些,但我会简单提一下。

Write Registry Settings With Custom Actions:有些人更喜欢直接通过自定义操作来编写注册表设置,因为这样他们就可以将逻辑添加到自定义操作以根据需要写入新值,否则使 msiexec.exe 远离值并且永远不会意外重置它们。从逻辑上讲,这不是最糟糕的方法,但是随着您增加风险,您也可能成为自己最大的敌人,因为自定义操作很复杂,很难正确执行,也很难很好地调节和排序。 .

Backup / Restore - or "Preserve Values Custom Actions":有些人不使用自定义操作直接编写精确设置,而是使用自定义操作来支持起来,然后在安装结束时整体恢复注册表设置。在我看来这不是一个好方法。非常笨重并且容易在其自身的权利中覆盖错误。 .

还有其他方法。