我在多台服务器上搞砸了基于WiX的安装程序,因此在卸载过程中不再删除文件或组件(甚至其他功能)。 MSI日志显示所有不会卸载的组件的PreviouslyPinned = 1。
我没有像使用SharedDll计数或甚至在不同安装程序之间共享组件那样花哨的事情。
我想我已将其追溯到我的WiX代码的特定版本。我做了几件蠢事。我(无意中)创建了一个带有空白Guid的非托管组件
<Component Id="file.ext" Guid="">
<File .../>
<Component>
我还更改了另一个组件的文件位置和Id(但不是它的Guid)。早期版本中的所有组件都显示PreviouslyPinned = 1且不会卸载,并且在此版本安装/卸载后正确添加了新组件。
如何让我的安装程序恢复正常并删除以前固定的组件?
答案 0 :(得分: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也应该更改)。 RemoveFile表概念可用于删除尚未注册为组件的安装和/或卸载文件(例如生成的文件)。
更新(2018年8月):只是想补充一点,如果你的应用程序依赖LoadLibrary / LoadLibraryEx或其他什么,你应该小心重命名你的dll或exe文件类似的结构“硬代码”文件名 - 要加载 - 深入源代码。
答案 1 :(得分:0)
更改组件的ID并使用有效的GUID可以使事情正确。
答案 2 :(得分:0)
简短的回答是:
是的,使用没有GUID的MSI组件是一种批量复制方法。复制并忘记。 当然,您必须添加一个:在每次重载或卸载之前删除所有文件(条件为“重新安装或修补或删除”)或重大升级。 没有它,它实际上没有意义。 您可以在自定义操作中执行此操作,即使使用CMD.exe / c RD / S / Q .... (当然,自定义代码比这更优雅)
如果你做得对,你可以设法进行非常简单的设置而不需要MSI通常拥有的所有陷阱。 当然,如果逐个文件地逐个删除整个目录,它会更容易。
尚未尝试,但我会:拥有没有GUID和普通组件的“动态”组件,然后提供补丁。从理论上讲,这应该可行,这对于修补程序之间高度变化的文件集导致的许多修补问题都是一个很好的解决方法。
答案 3 :(得分:0)
1。 事实上,没有GUID的组件是真正的“动态文件链接”方法,经常被一些工具或人员错误地称赞。
其他“方式”: 2.自动生成GUID只是一个自动化步骤(但当然是每个良好的设置构建基础架构的一部分:-) 在我看来,这不是动态的,因为如果你动态地制作它,你就错了:
2a上。生成每次完全随机的GUID =&GT;错误的算法
2B。仅在第一次创建组件时生成GUID,并对要在新组件中打包的新资源实现智能“差异”识别 =&GT;唯一有效的文件树同步方法。但是你可以在这里做错... 这是专家。