我在多台服务器上搞砸了基于WiX的安装程序,以便在卸载过程中不再删除文件或组件(甚至其他功能). MSI日志显示所有不会卸载的组件的PrevIoUslyPinned = 1.
我没有像使用SharedDll计数或甚至在不同安装程序之间共享组件那样花哨的东西.
我想我已将其追溯到我的WiX代码的特定版本.我做了几件蠢事.我(无意中)创建了一个带有空白Guid的非托管组件
<Component Id="file.ext" Guid=""> <File .../> <Component>
我还更改了另一个组件的文件位置和Id(但不是它的Guid).早期版本中的所有组件都显示PrevIoUslyPinned = 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或任何类似的“硬代码”文件名构造 – 你要小心重命名你的dll或exe文件 – 这些都是深入的源代码.