【问题标题】:Remove a GUID="" component installed with WiX删除随 WiX 安装的 GUID="" 组件
【发布时间】:2009-10-14 16:22:13
【问题描述】:

我在多台服务器上弄乱了基于 WiX 的安装程序,因此它在卸载过程中不再删除文件或组件(甚至其他功能)。 MSI 日志显示所有不会卸载的组件上的 PreviouslyPinned=1。

我没有什么花哨的事情,比如使用 SharedDll 计数,甚至在不同安装程序之间共享组件。

我想我已经追踪到我的 WiX 代码的特定版本。我做了几件蠢事。我(无意中)创建了一个带有空白 Guid 的非托管组件

<Component Id="file.ext" Guid="">
    <File .../>
<Component>

我还更改了另一个组件的文件位置和 ID(但不是 Guid)。早期版本中存在的所有组件都显示 PreviouslyPinned=1 并且不会卸载,并且在此版本之后添加的新组件可以正确安装/卸载。

我怎样才能让我的安装程序恢复正常并删除这些以前固定的组件?

【问题讨论】:

    标签: wix installation windows-installer uninstallation wix3


    【解决方案1】:

    Windows Installer 实际上支持空白 GUID 的概念。这意味着“安装,但不注册组件”:http://msdn.microsoft.com/en-us/library/aa368007(VS.85).aspx(ComponentId 条目解释了空 GUID 会发生什么)。

    我刚刚使用 WIX 进行了测试,它似乎尊重空白 GUID 条目(即没有自动生成 guid)。记住 绝对路径/关键路径GUID 之间的 1:1 规则:

    • 如果更改 GUID,则应为组件键路径使用新的绝对路径。
    • 如果更改绝对路径(例如通过重命名文件或移动文件),则应更改 GUID。

    总而言之,GUID 引用计数的是组件的安装密钥路径,而不是文件——它可能会移动,但是文件通过新的 GUID 具有新的身份(想想不同文件夹中具有相同名称的两个文件——它们是不同的文件,不同的身份)。

    清理混乱的 GUID 引用计数可能有点混乱。我发现如果我可以更改有效消除问题的文件名。我还生成了一个新的 guid,因此断开了指向旧 guid 引用计数的链接。您还可以重命名安装文件夹(理想情况下,这意味着所有组件 GUID 也应该更改)。 RemoveFile 表概念可用于在安装和/或卸载时删除尚未注册为组件的文件(例如生成的文件)。


    更新(2018 年 8 月):只是想补充一点,如果您的应用程序依赖于 LoadLibrary / LoadLibraryEx 或任何类似的“ 硬代码”文件名 - 要加载 - 在源代码的深处。

    【讨论】:

    • 我听到你说的是,由于空白 GUID 甚至不注册组件,它应该对其他组件没有影响。对吗?
    • 是的,一般来说,空白的 GUID 应该对其他组件没有影响,因为 MSI 在安装文件后会忽略它。但是,很少有一个事实没有修改:由空白 GUID 安装的文件将不会被卸载。如果这是一个版本化文件,并且您在添加回 guid 之前没有更改安装位置,那么理论上现有文件可能会阻止新文件版本的安装(如果现有文件是更高版本)。如果您使用较小的升级,还有其他一些不太可能出现的情况,但如果您不使用它,我不会进入它。
    • 感谢您的详细解答!最后,为了让其他所有东西都能正常卸载(从 MSI 日志中删除 PreviouslyPinned=1 引用),我必须进入该 PC 上的注册表并从 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion 下的安装程序中删除所有组件\Installer\UserData\\Components 基于我在这里找到的提示blogs.msdn.com/icumove/archive/2008/06/17/…
    【解决方案2】:

    更改组件的 ID 并使用有效的 GUID 应该可以解决问题。

    【讨论】:

    • 我希望通过“使事情正确”意味着允许所有 PreviouslyPinned=1 组件卸载。当我改变它时,这并没有发生。
    • 这个答案在这种情况下没有意义。使用带有 GUID 的组件是正常的方式,但这里的主题是没有 GUID 的组件。
    【解决方案3】:

    简短的回答是:

    是的,使用不带 GUID 的 MSI 组件是一种批量复制方法。复制并忘记。 当然,您必须添加一件事:在每次重装或卸载(条件“重新安装或修补或删除”)或重大升级之前删除所有文件。 没有它,它就没有任何意义。 您可以在自定义操作中执行此操作,即使使用 CMD.exe /c RD /S /Q .... (当然,自定义代码比这更优雅)

    如果你做对了,你可以设法进行非常简单的设置,而无需 MSI 通常有的所有陷阱。 当然,如果您逐个文件递归地删除整个目录,那会更容易。

    还没有尝试过,但我会:拥有没有 GUID 的“动态”组件和普通组件,然后提供补丁。从理论上讲,这应该可行,并且对于由于补丁之间的文件集高度变化而导致的许多补丁问题,这将是一个很好的解决方法。

    【讨论】:

      【解决方案4】:

      1。 事实上,没有 GUID 的组件才是真正的“动态文件链接”方法,经常被一些工具或人错误地称赞。

      其他“方式”: 2. 自动生成 GUID 只是一个自动化步骤(但当然是每个好的设置构建基础设施的一部分 :-) 在我看来这不是动态的,因为如果你动态地做,你就做错了:

      2a。每次生成完全随机的 GUID => 算法错误

      2b。仅在第一次创建组件时生成 GUID,并对要打包到新组件中的新资源实施智能“差异”识别 => 唯一有效的文件树同步方法。但是你可以在这里做很多错误... 这是为专家准备的。

      【讨论】:

        猜你喜欢
        • 2012-06-21
        • 2010-11-30
        • 1970-01-01
        • 2013-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-04
        相关资源
        最近更新 更多