我该如何确定是什么导致了重复的Windows Installer自我修复?

13
  • 如何仅记录Installshield 2008制作的MSI文件所做的更改,以便通过“自我修复”重新安装?
  • 什么是自我修复背后的原因?
  • 如何使用Installshield 2008禁用MSI的自我修复功能?

2
实际回答问题 :-). 1) 您可以在Windows事件日志的应用程序部分中找到自我修复记录的更改。查找事件源“MsiInstaller”,并查找ID为1001和1004的警告。 2) 自我修复是因为检测到正在启动的产品的不一致安装状态。 3) 您无法完全有意义地禁用自我修复,但是您可以禁用MSI软件包中的广告快捷方式,这将消除许多自我修复方案。有几种方法可以这样做。只是不要禁用Windows安装程序服务。 - Stein Åsmul
1个回答

22

自修,简单易懂的解释: 如果我删除一个文件,为什么MSI安装程序会重新配置?


备选答案可用

更新:现在有一种更短、更注重解决方案的答案可用,建议先尝试这个答案。这个答案侧重于"理解自我修复",而不是解释如何消除问题。您可能也想阅读本回答的第一部分。


意外的Windows Installer自我修复问题-快速解决方案?

这篇“文章”已经变得很大且有些难以阅读。这里是一个新写的前言-用于修复意外自我修复的简短"解决版本"(通常在VB6、Visual Studio、MS Office、MS Outlook、AutoCAD等中发现)。

  • 如果您遇到意外的自我修复第一件可以尝试的事情是直接手动创建一个桌面快捷方式,指向出现问题时启动的应用程序可执行文件。这样可以绕过最常见的自我修复触发器"广告快捷方式"。如果这样可以解决问题,您的问题就被"解决"了(或避免了)。下面是一个快速而详细的说明
  • 如果问题仍然存在,或者您的问题与加载MS OfficeMS Outlook附加组件或类似内容有关(无法通过快捷方式启动),那么您的系统很可能存在COM注册冲突,修复起来会更加麻烦。最简单的方法是在相关应用程序的附加组件对话框中禁用不需要的附加组件,看看是否可以解决问题。
  • 如果问题仍然存在,则通常需要调试真正的COM注册冲突(或冲突的文件/MIME关联或命令动词)。这通常涉及到系统上至少两个冲突的应用程序,在每次启动另一个应用程序后更新注册表时互相竞争(始终启动其中一个应用程序不会触发自我修复,冲突会在您在应用程序之间交替时出现)。还有其他可能性,请参见下面的更多详细信息:
    • "真正的解决方法"是联系两个应用程序的供应商要求他们为问题提供解决方案(因为解决方案通常需要修复两个供应商的MSI),但根据我的经验,这很少成功。尽管如此,请尝试一下,因为这是帮助所有长期受到困扰的人的方式!我曾经为银行部署提供了一个包含解决方案的设置,并且非常高兴我的问题得到了解决。
    • 要自行调试,您需要获取一个工具来打开系统上缓存的MSI文件,并且需要"hack"数据库——这是一个非常繁琐的任务,需要专家技能,如果您的桌面环境遇到非常严重的问题,建议寻求安装专家的帮助。它可以起作用,但不要期望奇迹。
    • 有关获取查看和修改MSI文件的工具的更多详细信息,请参见下面的"查找自我修复的触发器或罪魁祸首"部分。

本文的其余部分详细描述了自我修复问题。自我修复的潜在原因远不止本“简短”章节所述。


总体问题:开发人员调试和自我修复

Windows Installer是一种部署技术,其工作是安装指定的文件和注册表设置,并将它们保留在指定的安装位置,并确保它们是正确的版本 - 自我修复或弹性是实现这一目标的机制。它的操作与开发人员需要即时交换文件以进行调试、开发和测试的需求相冲突。

因此,许多自我修复(弹性)仅仅是由于开发人员尝试调试他们安装的应用程序并即时交换文件而触发。请参见下面的“一些典型的自我修复问题场景”中的第2节,了解如何处理这种情况。在其他情况下,存在MSI中的真正设计错误必须进行更正,或者会导致自我修复的系统管理陷阱 - 有时错误源可能很难找到。

我曾在serverfault.com上就自修问题发表过文章。那篇文章是针对系统管理员撰写的,现在看来可能比这篇(针对开发人员的)更易于理解。在stackoverflow上还有另一个更短的答案:为什么删除文件后MSI安装程序需要重新配置?(这可能是最简短且最容易理解的)。最后,我找到了一篇非常好的关于自修的文章,作者是Vadim Rapp如何解决Windows Installer尝试自修的问题。这篇文章值得一读。
如果Windows Installer确定正在启动的产品已正确安装,则不会发生自修。当自修发生时,需要更改系统上的某些内容才能使应用程序正常运行。

自我修复的主要原因

下面的部分"一些典型的自我修复问题场景"中详细介绍了详情,但是作为一个快速预示列表 - 主要原因包括:

1. 公司MSI文件打包不良或来自供应商的MSI设计缺陷(MSI软件包本身设计不良,由于各种原因意外触发自我修复)

  • 过度或错误地使用每个用户文件每个用户注册表键,通常将错误的键路径设置到用户配置文件中(而不是HKCU)。有关更多详细信息,请参见下面的第5节(以及此类情况的彩色插图)。
  • 错误的COM服务器注册(特别是来自Autodesk的VB6 COM文件VBA文件和库等产品)可能导致包干扰。
    • 两个MSI程序包从两个不同位置注册相同的COM文件(ActiveX / OCX),并在每次应用程序启动时进行“自我修复争夺”,以保持其版本正确注册。
    • 最后启动的应用程序会为自己设置正确的注册表,它会一直持续到另一个应用程序被启动并执行相同操作。一旦您在应用程序之间切换,问题就会出现。请参见下面的第7节以获取更多VB/COM自我修复详细信息
  • 组件密钥路径设置为一个空文件夹,Windows Installer在自我修复时移除该文件夹(触发无限循环的删除和随后的自我修复)
  • ACL锁定权限问题(已登录用户无法访问关键文件,Windows Installer重复触发修复)。这也可能是由外部进行的ACL更改引起的,但通常是由MSI本身引起的
  • 这里是serverfault.com正在进行的工作,描述了常见的MSI设计缺陷

2. 外部原因干扰导致文件或注册表键被删除,包括(登录)脚本、标准操作系统功能、病毒、安全软件等...

  • 临时文件被错误地安装到临时文件夹中后,Windows会自动将其删除。
  • 来自不良的登录和清理脚本以及清理应用程序干扰
  • 防病毒应用程序阻止或删除文件或注册表键,使Windows Installer无法检测或访问它们
  • 计算机病毒更改或删除文件和注册表设置
  • 过度活跃的电脑玩家和用户删除他们不理解的文件和设置

3. Windows设计更改、缺陷或限制导致有缺陷或问题的部署

  • 广告安装的MSI包无法安装(可能因为安装时间太长而被取消),并且会不断骚扰人们。严格来说,这不是自我修复,而是中止的广告安装,但结果是相同的:无限重新安装
  • 终端服务器问题。在终端服务器上通常完全禁用自我修复。这通常不会导致自我修复问题,但是应用程序安装缺少所需的每个用户文件或注册表键,可以通过自我修复的良性使用添加。然后仅缺少用户文件和用户注册表键,并且会出现问题
  • UAC干扰,证书验证失败以及由Windows设计更改引起的其他问题。对于每个版本的Windows,都会添加此类安全功能,并且通常最终增加了可靠部署的新障碍
  • 甚至某些Windows更新(更新、安全更新、热补丁等)都可以对如何执行MSI包的安全性进行重大更改,从而导致极其棘手的行为
    • 尽管这与MSI创建有关,而不是主要与其最终用户使用有关,但Windows Update KB3004394更新了Windows检查撤销根证书的方式,打破了旧版本Installshield命令行构建(针对数字签名设置)。现在已基本解决,但说明了Microsoft如何不断更改核心MSI功能
    • 以类似的方式,在安装Microsoft更新MS14-037“Internet Explorer版本6、7、8、9、10和11的安全更新”(KB2962872)后,Installshield崩溃了许多用户
    • 在安装kb2918614(Vista)后,Windows Installer基本功能发生了极其棘手的变化。突然之间,简单的MSI修复操作需要管理员凭据。这完全击败了MSI的一个核心优势:普通用户可以使用临时管理员权限运行批准的安装程序。安装此修复程序后还报告了其他MSI问题。似乎另一个Windows更新解决了这些问题:kb3008627(后来被kb3072630替换)

关于自我修复

Windows Installer旨在安装您的应用程序二进制文件、设置和数据文件,并保持它们已安装并确保它们是正确的版本。自我修复是实现这一目标的机制。总体概念称为弹性 - 即在启动应用程序之前,损坏的安装将触发自我修复。

弹性或自我修复是Windows Installer的一个内置主要概念不能以任何安全方式关闭。有时人们会做最难以置信的事情,例如禁用整个Windows Installer引擎来停止自我修复。这显然绝不能做。必须确定修复的原因,并解决问题,而不是创建新问题或黑客攻击系统。

每次启动广告快捷方式(本质上是指向Windows Installer功能而不是直接指向文件的特殊快捷方式),Windows Installer都会通过检查产品的"组件关键路径"来验证安装。如果发现差异,则会触发修复以纠正不完整的安装。"组件关键路径"是指在MSI内部为组件指定的"关键文件" - 每个组件都有一个。自我修复也可以通过实例化COM服务器(或尝试实例化)的人、通过其文件扩展名或MIME注册激活文件的人以及其他几种方式来启动。以下是Symantec关于"自我修复入口点"的全面文章: 使用入口点启动自我修复和广告功能

如果文件被删除、移动或简单地被覆盖(由用户手动或以某种自动方式),则可能会导致自我修复(如果文件或注册表设置未设置为关键路径,则不会触发自我修复)。


查找自我修复的触发器或罪魁祸首

自我修复的触发器通常可以在自我修复发生的系统的事件查看器中找到。按照以下步骤打开事件查看器

  • 右键单击"My Computer"
  • 点击"管理"
  • 如果出现UAC提示,请点击"继续"
  • 进入事件查看器部分,并检查Windows日志

或者可以执行以下操作:开始 => 运行... => eventvwr.exe,只查看事件查看器。如果在开始菜单中没有看到"运行",请按WIN键 + R

enter image description here


  • 在事件日志的“应用程序”部分中查找,您应该会发现来自事件源“MsiInstaller”的警告,其ID为1001和1004
  • 在上面的示例屏幕截图中,“产品代码”显示在红色框内
  • 为了确定产品代码所代表的产品,您可以通过此处解释的过程查找产品名称:我如何找到已安装的MSI设置的产品GUID?
  • 如果您真的想深入了解并检查MSI文件的实际内容,则必须获得能够查看MSI文件的工具(例如Orca、Installshield、Advanced Installer或类似工具)。然后,您可以打开“LocalPackage”路径列表中列出的软件包,如上一个符号链接答案中的屏幕截图所示。
  • 实际修改系统缓存的MSI文件和/或注册表以删除广告条目(例如广告)快捷方式、COM注册、文件关联、MIME关联或命令动词是专业人员的工作。这非常复杂,不是好的做法,但这是我所知道的唯一的“最后手段”。
  • 最后,一个应用程序可以显式调用Windows Installer本身来触发共享组件的自我修复-例如拼写检查器。我相信Microsoft Access的几个版本就是这样做的,据我所知,这种行为无法改变或解决。

MSI专家MVP Stefan Krüger有一篇关于同样自我修复问题的文章。他重要地讨论了实际事件日志条目及其含义。请在那里阅读有关实际调试过程的内容


一些典型的自修问题场景:

这是对上面概述中已经概述的几种自修问题场景的“冗长解释”。

  1. A component key path is set to an empty folder that Windows installer removes on self-repair (triggering an endless loop of removal and subsequent self-repair). This is solved by adding the folder to the CreateFolder table instead (Wix equivalent). In my experience this is the most common scenario for unwanted self-repair. Very common.
  2. Many self-repair problems are actually caused by developers trying to debug their applications by replacing files on the fly, deleting files or renaming them. Or they may use cleanup registry scripts and / or batch scripts to unregister and register COM files, COM-Interop, GAC files, file associations, or other common developer debug and development tasks.

    • This hot-swapping can triggering self-repair when the application is launched via an advertised shortcut.

    • A top tip for developers struggling with self-repair during application debugging is to not launch the application from an advertised shortcut, but to launch the main EXE directly from Windows Explorer or from a manually created shortcut. This will bypass the most common "self-repair entry point" - the advertised shortcut. Self-repair may still result from broken COM data, advertised file associations and a few other special cases (read this Symantec article for entry point information).

  3. Other applications or rather other MSI packages can break your installation and cause self-repair by interfering with registry data - typically COM settings, but also with other settings and files. These can be some of the hardest cases to solve, since the applications are basically fighting it out and the last one to run will update the registry each time. Typically both MSI files must be redesigned for the applications to operate on the same machine. Or, as is the order of the day, the whole application may be virtualized (for example: Microsoft App-V virtual packages) and run in its own sandbox which seems to be what is done more and more in companies these days. This error scenario is often seen with a suite of badly repackaged applications in a corporate environment. COM fragments from different packages overwrite the COM server's disk path from another package, and self-repair fighting ensues on each application launch via an advertised shortcut. The same file name with different file versions can also be registered from different file locations and share some registry settings that interfere. As far as I recall at least 7 variables or settings in the file system and registry must be in sync for a COM server to be properly instantiable. See section 7 below for a more specialized description of COM interference in the context of VB6 and VBA COM applications.

  4. A component key path is pointing to a temporary file that has been deleted by the application or it will be deleted by the system eventually via some sort of cleanup mechanism (can also be a cleanup tool such as ccleaner). This is common for files in the temp folder itself. This is solved by not installing the temp file, or putting the file somewhere else and making it permanent. I have seen this error most often in the world of corporate application repackaging where a faulty cleanup of the captured image leads to the install of a temporary file that should not have been included in the package at all. Often they may be temporary files waiting for a reboot to be installed to their intended, perhaps protected location, and the reboot was never performed - a common application packaging error. To a lesser degree I have seen it in auto-generated packages coming out of automated build systems.

  5. Permission problems: if a key file for a component is installed to a location that is not accessible for the user who invokes the application. Windows Installer might not "see" the installed file / key path, or be unable to add the file to the folder. These issues can be more exotic to debug, and may not happen that often. There are several variations on this issue:

    • An example of this is when you install a file to a %USERPROFILE% path and then forget to set a HKCU registry keypath, and instead set the keypath to point to the %USERPROFILE% folder/file. This generally yields an inaccessible hard coded key path that is user-specific: C:\Documents and settings\user1\Desktop. This path will not be found for another user logging on, and self-repair runs in circles. Here is a color illustration.
    • Another example is key paths set to folders that are not writeable for the System account. This may seem exotic but can result from the MSI's faulty modification of system ACL entries, or from a strange system administrator security setup, or any other non-standard ACL / Security Descriptor.
  6. Another class of self-repair problems emerges in relation to terminal servers and Citrix. The whole windows installer service could be locked down so any self-repair invoked to add per user data could fail and consequently self-repair may fail or more likely not run at all. This is reason enough to not rely on self-repair as a way to add user data like some MSI files do, and such constructs must be replaced with application deployment of user files copied from per-machine locations or the less effective ActiveSetup feature from Microsoft that runs once per user.

  7. VB6 applications and VBA applications, which are heavily COM based with massive potential for COM interference (COM settings overwriting each other and becoming inconsistent), have been known to trigger several mysterious self-repair problems, most of which have not been properly explained. This can also happen on launch of Visual Basic 6 (VB6) or Visual Studio (and many other applications). The common denominator is that some error in the current installation state triggered the self-repair, and you can track down the culprit product and component by following the steps outlined in the section above called "Finding the trigger or culprit for the self-repair". Be sure to report your findings here (I never use VB6 or VBA anymore - your detailed findings could help others with a long-standing annoyance).

    • Though I have never debugged such VB6 issues in great detail, it would seem that the problems result from applications that install common controls, VB6 COM files, templates and VBA files and libraries that conflict with existing files and registry settings and registrations on the box, or some per-user registry key or userprofile file may need to be added once per user (allow the self-repair to complete once and see if the problem goes away). In particular I have heard of these mysterious self-repair problems when launching AutoCAD (from Autodesk), Visual Basic 6, and several other products (often with VBA automation available in the tool).
    • Some applications even erroneously install bits and pieces from the VB6 runtime on their own causing these settings to be "ripped out" on uninstall of those applications. This can certainly cause self-repair to be triggered to fix the now (partially?) broken VB6 runtime. There are several variants of this problem, and the "catch all" solution is probably a complete uninstall and reinstall of the VB6 runtime. Here is a description of a very common "specific" problem involving a few COM registry keys. It nicely illustrates what happens in this scenario.
    • If you experience unexpected self-repair when launching VB6, AutoCAD, Visual Studio or other products, you can first try a workaround to prevent these unexpected self-repairs from happening in the first place (this doesn't solve the problem, but may bypass its symptoms): why does windows installer start up everytime i start up visual basic 6
    • See my comment to the question in this topic for one of the most typical VB6 style self-repairs: Why does my application triggers the Installer of another application? (ActiveX control registered twice from two different locations on disk).
    • In my opinion the "general fix" - that should always work - for VB-COM self-repair issues, is to get the vendor to update their project in question to use the latest official and properly installed and shared ActiveX control / OCX available, and not to rely on their own version installed redundantly and registered in the wrong location.
  8. A special case of Windows Installer repair or self-repair that is worth mentioning for completeness, was the issue with Microsoft Office several years ago where a self-repair would be triggered, and you would be asked to insert the Microsoft Office installation media (in those days CD-ROMs or DVDs - today maybe thumb drives). As far as I recall this was related to an erroneous call to the built in Windows Installer standard action "ResolveSource" which unexpectedly (and unnecessarily) triggered the prompt for the installation media. A very common support call back in the day and mentioned here for completeness. It is important to note that this problem can still occur whenever MS Office is installed from any removable media (rather than the better option of a network share). This happens when MS Office detects that it needs to install further, optional (and usually shared) components of the product that were not installed originally. For example unusual spell-checkers, various templates or specific and rarely used tools. It is possible to install these components to "install on first use" (advertised features is the proper Windows Installer term).

  9. There are many other possible scenarios. To mention a few:

    • a bad logon script may delete things on the system and trigger self-repair
    • an AD advertised package may fail to install and keep bugging people
    • two applications may start fighting for the same file associations
    • computer tinkerers and hackers can manually delete data that trigger self-repair
    • anti-virus can quarantine files and registry settings that trigger repair
    • a virus can change or delete things and trigger self-repair
    • a disk and registry cleanup tool such as ccleaner can delete files and trigger self-repair
    • and no doubt numerous other scenarios...

自我修复的良性用途

最后,存在一些 自我修复的良性用途,它们只会发生一次,不构成错误。这是 自我修复的合法和正确使用方式,尽管可能与设计错误一样令人烦恼,并且在用户干预下可能会反复出现:

  • 自我修复有时用于向HKCU用户配置文件中添加每个用户数据。这种设计基本上是有效的,但随着新的部署障碍不断出现,它在每个Windows版本中变得越来越糟糕。首先,自我修复通常在终端服务器上根本不起作用,导致安装不完整。虽然这与本讨论无关,但最好将应用程序复制到每个用户位置。另一个问题是UAC。其他问题随着每个新的Windows版本甚至一些Windows更新的出现而出现(虚拟文件夹重定向,证书提示,以前不存在的目标路径限制等等...)。
  • 当需要使用自我修复来设置用户数据时,可能需要很长时间,以至于用户会中止并持续中止。这会导致自我修复一直出现,直到被允许完成。这是一个常见的支持电话。
  • 还可以安装具有"广告功能"的产品,这些功能旨在在应用程序使用期间触发"按需安装"。很少有应用程序使用此功能,但是当使用此功能时,可能会运行冗长的"自我修复样式"安装程序-下载所需的文件和设置。 如果取消此过程,则会回滚该功能的安装,并且可以再次触发。由于多种原因,此安装可能很
    • 如果安装程序使用大型压缩CAB文件,首先下载然后在慢速磁盘上提取,其中防病毒软件开始扫描整个cab然后扫描每个提取的文件,操作可能需要很长时间。
    • 如果网络连接是无线的,并且有大量小文件需要下载(高延迟),那么操作也可能很慢,而且防病毒软件可能会减慢速度。
    • 如果从可移动介质安装,则可能会提示插入源介质以允许复制文件。如果在办公环境中使用可移动介质(不应该这样做-请在网络共享中进行管理员安装),则非常常见的支持电话
    • 等等...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接