我正在使用WIX创建安装标准文件的MSI(没有exe,com,DLL等)。在某些用户计算机上,MSI中的某些文件可能已经存在。在安装过程中这不是问题,因为MSI会自动更新较旧的文件等。但是,在卸载过程中我遇到了问题。
最简单的解释一个例子:
Joe Bloggs在他们的计算机上有“文件B”。此文件尚未由MSI程序包安装,并且无论如何都不会被Microsoft Installer系统跟踪。它只是计算机上的普通文件。
Joe Bloggs下载并安装我的包,其中包含“文件A”,“文件B”和“文件C”。当他安装我的软件包时,Microsoft Installer系统会检查“文件B”并确定它与我的软件包中的“文件B”相同。因此它不会替换“文件B”,但它会标记文件B是安装的一部分的MSI组件。
Joe Bloggs然后决定他不喜欢我的软件,所以卸载我的软件包。当他这样做时,尽管在我的软件包安装之前存在“文件B”,但所有3个文件都被删除。我的调查已经确定这是因为包含“文件B”的组件被标记为已安装。因此,当您卸载软件包时,它会删除“文件B”。
这有点技术性,但希望有一位知道解决方案的WIX / MSi专家。
由于
吉姆
答案 0 :(得分:3)
如果文件可能已存在于机器标记Component/@SharedDllRefCount="yes"
如果Windows安装程序发现已存在的文件,则会自动更新引用计数。
答案 1 :(得分:2)
这通常通过备份和还原自定义操作来完成。
基本上,您编写了一个自定义操作,可以根据收到的参数复制某些文件。然后,您可以在安装程序中使用此自定义操作两次:
答案 2 :(得分:2)
使用MSI时这是一个已知的“问题”,通常是由错误的部署策略引起的。缺少引用计数实际上仅仅是容易出错的部署方法的症状。
在安装运行之前,安装程序几乎不会干扰存在或可能存在的文件。这包括您自己安装的文件,这些文件是由您自己的另一个安装程序计算的!想想凝聚力和耦合,只有一个安装程序应该处理每个文件。
这个一般规则通常会触发“我们的案例很特殊”的回应。相信我,事实并非如此。应用程序应在Program Files下使用自己的安装文件夹,在用户设置下使用自己的文件夹,在共享设置中使用自己的文件夹。它应该从不替换或更新共享文件,例如用户词典,排除列表或类似文件。
这种方法通常是为了促进“开发人员注册”,其中配置文件需要应用程序的默认值才能运行。完全不能接受。应用程序本身可以访问共享文件,如果它有访问权限,甚至可以更新它们,但它可以不用“默认设置”替换整个文件,或者在卸载时卸载整个文件。 在没有基本配置文件的情况下创建运行环境是一项应用程序职责。这些文件应该从应用程序内部默认值生成,或者从放置在别处的只读默认文件中复制。
如果您在不同的安装程序之间共享配置文件,我会使用合并模块部署它们,或者只是将包含文件的组件设置为“共享”并且“永久”和“永不替换,如果已存在”。这样做应该是您所描述的症状的“简单修复”,即使您不遵循我上面推荐的部署建议。
答案 3 :(得分:0)
我知道的唯一方法就是破解注册表。如果你增加
MSI完成创建后的 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLS\<your dll name>
值,在卸载过程中,MSI会看到该文件仍在使用中,而不是将其删除。这非常hacky,但它会起作用。
或者您可以将文件备份到其他位置,卸载后将其复制回来。
答案 4 :(得分:0)
让我尝试添加一个比我之前写的更好的答案。我似乎没有正确地阅读这个问题。我将尝试将其分解为几个选项:
带有MSI组件的良好的经验法则是,一旦您为组件定义了一个密钥路径(注册表或磁盘上的绝对路径),Windows Installer就会认为它是&#34;拥有关键路径&#34;并将参考计算它。如果ref-count为1,则删除密钥路径以及卸载时组件中的任何其他内容。