MSI 未卸载 .dll 文件
Posted
技术标签:
【中文标题】MSI 未卸载 .dll 文件【英文标题】:MSI not uninstalling .dll files 【发布时间】:2016-03-07 05:13:29 【问题描述】:我有一个程序用于正确卸载并在卸载期间删除与其关联的所有文件。我们已经改进了安装/卸载过程,现在可以使用 installshield。
在之前的安装/卸载过程中,它运行良好,直到我们更改它之前的大约 2 周,即使现在使用新的 installshield 安装程序,卸载时也无法删除 .dll 文件。
我认为问题不在于安装人员本身,因为我们在使用 2 种截然不同的方法时遇到了完全相同的问题。
目前为了使卸载过程正常工作,我们使用控制面板卸载它,然后手动删除剩余的 .dll 文件
此问题发生在具有这些组件的所有机器上,并且所有组件都会发生。 所有机器同时启动有问题。
在我的 installshield 过程中,我将详细的日志记录输出到 .txt 文件中,我不知道如何才能最好地显示文件中的所有信息,而不仅仅是大量转储。
【问题讨论】:
【参考方案1】:这通常与保存 dll 的组件的共享标志设置为 yes 有关。这增加了HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs
注册表中的SharedDLLRef
计数。结合 Installshield 错误,这可能会使文件处于卸载状态。解决方法是将保存文件的组件设置为 shared=no 并删除SharedDLLs
中的条目,然后再次尝试卸载。
此 sharedDLLs ref Count 是与非 msi 安装程序的兼容性功能,我认为不应该用于系统 32 的文件。使用组件 guid 的 MSI 引用计数。
更新:启用 SharedDllRefCount 会在此处设置旧版引用计数:
64 位:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs
32 位:HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDLLs
清理:
Cleaning Up Your Shared DLLs Registry References for MSIs(未经我测试)。 And some further MSDN suggestions for stranded components。 Comprehensive explanation of reference counting errors。【讨论】:
您能澄清一下您所指的错误吗?我知道的所有案例都涉及编写不当的组件,通常会违反组件规则,可能会因在测试版本之间运行小更新或小升级而恶化。【参考方案2】:其中一些原因是:
组件曾经被标记为永久的,或者被赋予了一个空的 guid。这些是传播到系统的设置。如果您使用这些设置进行安装,它们会粘在系统上,并且在项目中关闭它们不会改变这一点。
Stein 的回答 - 在安装时标记为共享。除非您知道非 MSI 安装可能会在安装后将相同的文件安装到相同的位置(并设置 SharedDllRefCount),否则永远没有理由这样做。
还有另一个共享位 msidbComponentAttributesShared,它告诉 Windows 它在多个 MSI 之间共享,即使它不在某些安装中。除非您正在修补,否则不太可能。
运行类似这样的 VBScript 来枚举系统上的每个组件会告诉您 Windows 是否认为它属于已安装的产品:
Option Explicit
Public installer, fullmsg, comp, a, prod, fso, pname, ploc, pid, psorce
Set fso = CreateObject("Scripting.FileSystemObject")
Set a = fso.CreateTextFile("comps.txt", True)
' Connect to Windows Installer object
Set installer = CreateObject("WindowsInstaller.Installer")
a.writeline ("MSI Components")
on error resume next
For Each comp In installer.components
a.writeline (comp & " is used by the product:")
for each prod in Installer.ComponentClients (comp)
pid = installer.componentpath (prod, comp)
pname = installer.productinfo (prod, "InstalledProductName")
a.Writeline (" " & pname & " " & prod & "and is installed at " & pid)
Next
Next
【讨论】:
以上是关于MSI 未卸载 .dll 文件的主要内容,如果未能解决你的问题,请参考以下文章