如何避免使用我的 WiX / MSI 包触发 MSI 自我修复?

Ste*_*mul 4 windows-installer installshield wix advanced-installer

如何避免从我的 WiX 生成的 MSI 包触发自我修复?


这是一个Q/A 风格的问题,其答案只是列出了一些不要在您的 MSI 文件中做的事情,以避免重复自我修复的最常见原因。

Ste*_*mul 5

自我修复,简单且简短的说明为什么删除文件后 MSI 安装程序会重新配置?


一般 WiX / MSI 建议:此自我修复部分与一般 MSI 问题的原始答案分开: 如何避免 WiX / MSI 部署解决方案中的常见设计缺陷?


简短的摘要

我一直试图写关于为开发人员重复 MSI 自我修复的文章,但最终写得太详细了。这是我的最后一次尝试:关于不要在 WiX/MSI 文件中做什么的具体设计建议。其他部署专家,请扩展下面的“陷阱列表”。


早期的答案我写的竟然是开发商有关,但不适合开发者:

我认为现在是时候从另一个角度来看待自我修复了。现在我终于可以写出我一直以来的意图:开发人员对自我修复的看法-为自己进行设置开发工作的开发人员避免的一些陷阱- 通常使用WiX 框架。只是一个简短的具体清单,列出了在您的 MSI 包中不要做的事情。


MSI / WiX 设计陷阱导致自我修复问题

这是一个粗略的初稿。这些要点将在时间允许的情况下充实。

  1. 你搞砸了共享运行时的安装。您不使用合并模块来部署全局注册和/或共享运行时文件。而是安装自己的文件副本并在系统范围内注册它们。这对 COM 文件尤其不利,但也适用于其他类型的文件。冲突的应用程序将尝试恢复它们的状态,并在每次替代应用程序启动时导致“自我修复战斗”。

  2. 您遇到了空文件夹自我修复的特殊性。您可以使用目录键路径创建一个空组件,而无需添加 CreateFolder 条目。这会导致无限循环,其中 MSI 删除文件夹,然后触发自我修复将其放回原处。此时,WiX 中可能会对此提供保护。

  3. 不正确的组件引用计数。您自己创建了一套软件包,这些软件包使用不同的组件 GUID 从不同的 MSI 设置将具有相同名称的文件安装到磁盘上的相同位置。这很可能会触发自我修复,因为软件包会“争取”将其文件版本放置到位。对此有几个“修复”,例如设计合并模块、使用 WiX 包含文件、在没有引用计数的情况下安装文件(空白组件 guid) - (更多细节将很快添加)。

  4. 错误的每用户文件安装。您将文件安装到用户配置文件并在 HKCU 中设置文件键路径而不是注册表键路径(MSI 设计指南要求)。这经常会导致普通用户体验到由于缺少磁盘权限而永远不会成功的重复自我修复。密钥文件不会被普通用户“看到”,因为密钥文件所在的位置(另一个用户的用户配置文件)没有读取权限。这是彩色插图

  5. 错误的磁盘/注册表自定义权限。这个问题不同,但与上一个问题相似。您在安装过程中应用自定义文件、文件夹和注册表权限,从而删除普通用户对安装位置的读取访问权限。普通用户会看到重复的自我修复永远不会成功。这也可能发生在“每台机器”文件位置,而不仅仅是用户配置文件路径(如上一期)。我听到有传言说有些人也看到了这一点,特别是写保护的 ini 文件。

  6. 您为临时文件启用引用计数。出于某种疯狂的原因,您决定将文件安装到 tmp 文件夹或其他可能随时清理的文件夹。也许您打算从自定义操作或其他操作中运行该文件。在任何一种情况下,您都通过具有组件 guid 和密钥路径集的组件安装它,并且当文件从磁盘“清除”时,您的 MSI 文件将尝试将其放回原处。每次“清理”文件时都会重复此操作。由于安装位置可能是每个用户的位置,其他用户可能不会从他们的登录中“看到”该文件,他们会立即体验到重复的自我修复,而您只能在“清理”文件时才能看到它。

  7. 恶意软件 - 真实和误报。您安装了一个不寻常的二进制文件,而无需通过基本的病毒/恶意软件筛选来运行它。检查实际恶意软件与检查误报同样重要(使用的一种恶意软件扫描服务是http://www.virustotal.com - 几乎 70 种不同的扫描程序 - 特别注意主要供应商 - 显然) . 因此,您忽略了恶意软件检查,并且在部署后您的产品会遭受来自多个防病毒供应商的误报,并且自我修复将徒劳无功地尝试放回文件只是为了再次“隔离”它. 你的客户责怪你。如果您实际上安装了真正的病毒或恶意软件,结果当然同样糟糕。结果完全一样——自我修复一直白费。另一方面,如果二进制文件安装后被感染,那么自我修复应该达到目的并运行一次以将干净的文件放回原处。主要问题修复误报实际上比处理恶意软件更难(如果恶意软件导致数据丢失,对客户来说当然更糟,但可以理解的是,作为软件提供商,这超出了您的控制范围)。对于恶意软件,您只需告诉您的客户重建他们的 PC 并重新安装您的软件,但是对于误报,您需要做一些事情将您的二进制文件列入白名单- 经常与几个安全软件供应商合作。你如何处理这个过程?随着恶意软件似乎变得越来越糟糕,并且以任何可能的方式试图加强安全性,误报很可能成为一个主要的部署问题——甚至比现在更严重。尝试将二进制文件列入白名单可能会浪费大量时间。显而易见,但让我们大声说出来:作为部署人员,不要独自承担这项任务 - 此白名单是一项需要管理层参与的艰巨任务。这个问题会影响软件供应商的一切:销售、开发、营销和支持。随着安全软件变得更加先进和“智能” - 他们可能会开始隔离在系统上找到的整个缓存的 MSI%SystemRoot%\Installer(用于维护安装、修复和卸载)。发生这种情况时,将无法进行自我修复 - 也无法卸载 (!) - 除非您可以访问用于安装的确切原始 MSI。在这些情况下,我想您可以尝试使用此处列出的一些选项来卸载带有恶意软件或误报的MSI为什么 MSI 需要原始 .msi 文件才能继续卸载?或此处的第 12 节:在不使用 msiexec 的情况下从命令行卸载 MSI 文件

  8. 您安装的桌面文件可能会被用户删除。这是一个“边缘情况”,要求您还错误地将安装组件的密钥路径设置为磁盘密钥路径(而不是正确的 HKCU 路径)。大多数情况下,您将快捷方式放在桌面上,这很好。但是,如果您安装了用户随后删除的某种数据文件,则当您的应用程序通过宣传的快捷方式启动时,或者即使宣传的 COM 对象已实例化或特定文件类型,您可能会看到它通过自我修复恢复推出。

  9. 您将宣传的快捷方式安装到“启动”文件夹。不要将宣传的快捷方式安装到“启动”文件夹。它可以触发自我修复以在每次系统启动时运行,而无需进行任何用户交互。据报道,删除快捷方式也会触发自我修复。这是我从未真正见过的东西,但它是有道理的。

  10. 您使用应用程序更改的 HKCU 密钥路径(或 HKLM)。您从 MSI 写入注册表的任何设置通常都不应被修改,或者更糟的是,您的应用程序的操作不应将其删除。可能会导致自我修复。只写入应用程序刚刚读取的数据。您的应用程序本身应始终将所有默认设置填充到 HKCU,并且您的设置不应干扰它们。用户配置文件也是如此。应该从每台机器的模板位置为每个用户复制它们。故事的总体寓意:仅部署每台机器的文件和设置 (HKLM)。其他一切都应该由应用程序初始化:为什么在使用 MSI 时将文件部署限制到用户配置文件或 HKCU 是一个好主意?.

  11. 您的设置写入注册表项,这些注册表项会定期被组策略覆盖。我相信我第一次看到这个问题与使用 MSI 设置 HKCU 中的某些 IE 代理设置键有关。出于多种原因,使用 MSI 仅设置几个注册表项总是一个坏主意。请参阅此 serverfault.com 回答以获取几个问题的列表:用于 reg 部署的 MSI 包(推荐快速阅读,虽然它与系统管理员最相关,但对于开发人员来说很重要)。我无法重现此问题,因为在缺少关键路径(通常不仅仅是更改或修改)时会触发自我修复。也许组策略实际上删除了 MSI 添加的 HKCU 值?我们确实看到了问题,所以这可能就是发生的事情。总体信息:永远不要使用 MSI 来设置几个注册表项,特别是如果它们在 HKCU 中。使用组策略、登录脚本、VB 脚本、PowerShell 或其他更可靠的措施,例如让应用程序在启动时执行此操作(每个用户一次)。

  12. 您在 MSI 文件中注册了特定的文件/MIME 关联或命令动词。大多数自我修复似乎是由产品之间的 COM 注册表干扰触发的,这些干扰触发了 COM 对象实例化的自我修复,或调用了宣传的快捷方式。但是,您也可以通过文件/MIME 关联和命令动词触发自我修复。特别是文件关联可能被系统上的其他应用程序/MSI 文件注册,这可能会触发非常持久的自我修复,因为每个应用程序都试图“窃取”文件关联。在您的 MSI 中谨慎使用这些功能 - 并确保您注册的文件关联确实是独一无二的。切勿在 MSI 设置中设置“通用”文件关联(例如 jpg)。

  13. 错误地安装了相同的 MSI 两次(或更多)。这听起来很奇怪,但实际上有多种可能。如果发生这种情况,自我修复可能不是您最大的问题,您也会看到其他问题:

    • 您忘记为重建的 MSI 生成新的包 GUID。然后,Windows Installer 将两个不同的 MSI 文件“根据定义”视为同一个文件。我相信在这些情况下我已经看到了自我修复,但是您也会面临许多其他问题,所有问题都同样奇怪。始终自动生成包 GUID。任何两个 MSI 文件都没有理由具有相同的包 GUID(除非您在 Windows 安装程序引擎中测试一些非常晦涩的东西)。虽然完全意识到重复 GUID 的问题,但多年前在一些非常忙碌的开发过程中使用 Installshield 时仍然发生在我身上。我仍然想知道它实际上是如何发生的 - 但它确实发生了。也许这是工具中的一个未知错误?
    • 失败的主要升级可能会同时安装两个版本的设置。您会在添加/删除程序中看到两个条目。在这些情况下,自我修复问题是可能的,但还有许多其他问题。根据我的经验,这个问题很严重,但没有对两个 MSI 文件使用相同的包 GUID 严重(上一个要点)。
    • 我敢肯定,同一个产品还有多种其他方式可以被多次安装。也许失败的多实例转换也会导致问题?我不喜欢那个特定的概念,所以我还没有真正尝试过。

一些一般的“亚军”自我修复相关问题:

  • 在您的 MSI 上运行验证,上述几个问题将被标记并轻松消除。
  • 切勿在您的开发人员盒子或任何您无法轻松恢复的机器上运行MsiZap.exe。事实上,根本不要使用这个“工具”。在 MsiZap.exe 对 MSI 数据库进行核攻击所创建的“脏状态”之上进行部署时,您经常会看到自我修复问题。
  • 如果您需要安装COM shell 扩展,请确保在使用Windows Explorer 时进行彻底测试,并在不同的视图模式之间切换以检查自修复是否启动。这样的COM 对象本质上是在持续使用中,因此自修复如果任何设置受到干扰,很可能(确定)。
  • 如果您将广告快捷方式单独放在一个功能中,它几乎不会触发自我修复。对快捷方式所在的功能及其所有父功能进行了关键路径检查(我上次检查;-) - 这是几年前的)。

自修相关解答(保管链接):


归档时间:

查看次数:

2263 次

最近记录:

6 年 前