5

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

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

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

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

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

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

4

4 回答 4

5

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或任何类似的“硬编码”文件名​​的构造 - 要加载 - 深入源代码。

于 2009-10-14T17:22:08.923 回答
0

简短的回答是:

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

如果你做对了,你可以在没有所有陷阱的情况下进行非常简单的设置,MSI 通常有。当然,如果您逐个文件递归地删除整个目录,则更容易。

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

于 2013-08-20T09:39:57.537 回答
0

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

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

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

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

于 2013-08-20T09:44:10.117 回答
0

Changing the id of the component and using a valid GUID should make things right.

于 2009-10-14T19:24:41.557 回答