Wix工具集:如何在卸载时恢复替换文件

时间:2017-10-02 09:16:32

标签: wix windows-installer installer

我有两种产品 - 产品A和产品B.

产品A包含版本1.0.0的文件A.dll。或任何其他类型的文件(.config与文本1.0.0)。 产品B使用版本2.0.0(或使用文本2.0.0配置)更新文件A.dll。

卸载产品B后,它会删除A.dll。 如果我在产品B中将A.dll标记为" rermanent"它不会被删除。

但是我需要在卸载产品B后恢复A.dll版本1.0.0。

作为一种可能的解决方法,我可以在"恢复"中运行产品A.安装模式。

还有其他解决方案吗?

P.S:案例: 产品A已经发布,由于一些错误,接下来需要热修复作为产品B(在程序和功能列表中有额外的条目)。 产品B(热修复)用更新的产品替换A.dll。 我想支持卸载产品B(热修复)并在安装之前返回状态(A.dll版本1.0.0)。

3 个答案:

答案 0 :(得分:1)

注意:这个答案是在OP修改他的问题之前写的。

在我看来,这表明应用程序设计中存在错误。您正在处理的是两个不同版本所需的共享文件 - 或者看起来如此?产品A可以使用版本2.0.0的dll,还是绝对需要版本1.0.0?

简短回答

  1. 在主应用程序的安装文件夹中安装您现在共享的dll作为私有dll (对于每个产品,在他们需要的版本中),或者。 ..

  2. 确保两个产品都可以在共享位置使用最新的dll(共享部署,要求完全向后兼容)。

  3. 您还可以安装两个dll版本并排(在.NET程序集的 GAC WinSxS for Win32文件)或磁盘上的其他位置,两个应用程序都可以访问它们(它们加载他们需要的那个 - 并在卸载时保留其他版本)。哪个版本加载取决于应用程序清单(有些人发现清单搞砸了dll-hell的第二次出现 - 加载了错误的东西)。

  4. 最后,您可以静态链接 dll到您的主要可执行文件(我最不喜欢的大公司部署选项 - 详情如下)。 .NET中的静态链接与本机Win32二进制文件有点不同:Static Linking of libraries created on C# .NET。我不确定静态.NET链接的性能影响(我只做Win32静态链接)。

  5. 作为经验法则共享文件必须相当稳定,几乎没有更新才能真正用作共享。他们通常是"图书馆"。我可能会选择在开发期间部署私有副本一段时间,直到我达到更稳定的状态并切换到共享文件(并排或全局,无论哪个适合)。

    如果您正在与COM打交道,那么该技术的整体注册性质就会受到影响。使得必须保持向后兼容性(文件总是共享)或者您可以尝试" registration-less COM" -  本质上是COM嵌入在清单文件中的注册表信息和主应用程序安装目录中所有文件的本地副本 - 一切都发生在"隔离"时尚。 COM已经过时了,但由于它通过COM Interop用于.NET,因此在未来几年内它将继续成为每个人的头疼。

    以下是对这些选项的更详细讨论。它有点乱 - 就像它刚刚写下你的头顶一样。我会尽快清理它,并且可以更清楚地看到它有什么问题。

    如果产品A可以使用版本2.0.0,那么您在应用程序之间有一个基本共享文件,安装它的正常方法是两个安装程序都包含merge module。您应该具有向后兼容性,以便产品A可以使用该文件的任何版本,包括版本2.0.0。产品B还应该能够使用任何版本的共享dll,并且您应该能够将升级部署到两个产品都可以处理的共享dll。一个真正共享的文件。在产品安装期间,应始终安装更高版本的文件,并且使用该文件的所有产品都应该能够处理新版本(向后兼容性)。如果您有快速可靠地部署到许多产品的安全热修复,而无需单独重建所有产品,那就太棒了。这显然是共享文件的用途。

    如果产品A不能使用版本2.0.0的dll,那么您可能有并排安装方案(如全局程序集缓存 - 不同版本的同一个程序集同时安装,应用程序加载他们需要的程序集。您应该在不同的位置(具有不同的文件名)安装dll的两个版本,并且您的产品A和产品B应该加载他们需要的版本。或者您应该安装到GAC - 这是GAC的用途(仅限.NET程序集)。对于普通的Win32文件(Windows side-by-side assemblies),还有一个并排的概念。你必须永远不要在WinSxS文件夹中直接乱用(Win32 dll的Windows程序集文件夹),see this excellent explanation from Advanced Istaller - 就像GAC文件注册安装到WinSxS一样。当您卸载产品A或产品B时,其他应用程序所需的dll保持不变(也可能有其他产品使用它们)。并排文件也可以在产品之间共享,但是如果在您的产品卸载时注册了其他需要它们的产品,那么它们将无法卸载,并且有多个不同版本的文件可供选择,因此你至关重要的是不需要保持不同的"分支之间的向后兼容性。 (必须仍然为每个分支保持向后兼容性 - 即版本1.0.1必须与1.0.0兼容,但不能与2.0.0兼容。)

    最明显的选择可能是将您现在共享的DLL包含在产品的主应用程序文件夹中 - 使其成为" 私人文件"从未尝试在其他应用程序/产品之间共享。这最适用于Win32 DLL或.NET程序集(无注册表影响或全局注册 - 除非为.NET Interop注册.NET程序集)。 COM文件在注册表中在系统范围内注册,应安装到具有真正向后兼容性的共享位置,或者与旧版本并行提供(使用新接口 - 很少使用)。如果您需要并行部署,.NET程序集可以并行安装在GAC中,或者您可以将它们部署到主应用程序的目录中作为"私有副本"大会。

    因此,对于许多产品使用的文件,您有共享文件共享并排文件,在dll中安装dll的私有副本应用程序的主安装文件夹和最终选项是静态链接 - 将dll编译到产品的主要可执行文件中。只是提到这一点,因为有些人更喜欢这个选项。它不允许部署对共享文件(或文件的私有副本)的更新,但对库的任何更新都需要完全重新编译和重新部署这两种产品(或者我们正在谈论的产品) - 很多工作。人们可能会首先发现这个选项很吸引人,但很快就会厌倦。这完全取决于您的应用程序和共享组件(现在静态链接)将进行多少更新。我们经常重复这一点:这一切都取决于,但确实如此。

    这完全取决于:-)关于您如何设计应用程序以及您希望部署在产品之间共享且可以自行更新的文件的数量。在主应用程序exe(而不是静态链接)旁边部署dll的私有副本的好处是,您可以提供更新的dll而无需重新编译整个应用程序exe(这可能很大)。您最大限度地降低了在应用程序的其他部分引入新错误的风险,并且您提供了一个小小的修补程序"您的产品,而不是完整的重新编译与所需的所有QA工作。你有一个有针对性的dll-fix和一个新的UAT / QA设置(如果你做得好,那个设置也可以作为补丁提供)。

    我喜欢的(真正的)共享文件是我可以使用可以自行更新的单独设置来提供它们,而不会影响主要产品的设置(当我真实地说我是指几十个应用程序使用的文件,而不仅仅是一对应用程序。这很好地解耦了所有需要的东西是在共享文件已被"热修复"之后主要应用程序的一些QA / UAT。没有完全重新编译您的主要产品以及QA / UAT的新设置。如果您提供许多大型产品,这一点非常重要。 您可能会面临许多其他应用程序使用的共享文件的一些非常重要的安全热修复。我在大型公司中看到了很多,例如银行 - 您可能需要花费数周或数月的时间来更新在其他几十种产品中存在同样的问题。对每个人来说都是一场噩梦。

    我应该补充一点,这是个人观点,我不太喜欢合并模块。这是一个好的概念,但是对于所有意图和目的而言,它相当于静态链接以进行设置。不完全,但几乎 - 编译时包含的所有文件都是我的意思。然而,好消息是,只要升级后的合并模块中有更高版本的文件(在新设置中),合并模块的升级版本就可以包含在另一个升级相同文件的设置中。所以它并不是静态链接",但它有点像它。

    我的个人偏好:如果真的有助于保持大量产品的更新和热修复,请使用共享文件。在大多数情况下,这些共享文件非常稳定,几乎没有(呃)更新,并且因为这项工作很好地共享(你会在某些时候感谢自己 - 当某些东西确实达到安全性时)。通过自己的设置部署共享文件,并将该设置设置为您自己的产品设置的先决条件。事实证明,这对我来说是最灵活和最完整的 - 特别是在大公司(用于内部软件)。你可以将它与WiX的Burn之类的引导程序一起链接(在公司中,你将使用像SCCM这样的部署系统来设置依赖项),并且可以单独为共享文件和应用程序文件提供更新。如果您的应用程序很简单且共享文件不太稳定,只需在主安装目录中部署dll的私有副本(除非它是COM文件)。我会避免过多的静态链接(我只喜欢最小依赖性场景的静态链接 - 就像为WiX设置制作自定义动作dll并希望它运行一样在任何没有依赖的机器上。)

    良好的部署取决于良好的开发决策。这是所有的凝聚力和耦合。只有拇指规则,没有办法适合每个人。无论你做什么,它都会做很多工作,但要尽量避免影响太多需要完全开发/部署发布周期的应用程序的小变化 - 这是共享文件的总体目标。

答案 1 :(得分:1)

如果这些是单独的产品,为什么要在另一个上面安装一个?这是一个临时使用的UAT / QA构造吗?您可以并排安装这些产品(在每个产品的单独文件夹中),然后只需退回您不再需要的任何版本吗?你的情况是拉回你的"新的"与原始安装混合的安装与Windows Installer不兼容。

这是已发布的产品还是您仍在开发中?为什么不拉回盒子上的内容并安装新版本的设置,清理所有内容。您可以创建升级表以卸载已部署的现有产品。出于安全原因,我会更改您安装的新版本的路径,我会在InstallExecuteSequence的早期卸载现有的软件包。

总体信息:您不应在同一安装位置混合使用不同的产品。每个产品都应该有自己的安装文件夹,如果你有几个设置安装到同一个位置,那么文件应该安装相同的组件guids。

看看这对您是否有意义:Change my component GUID in wix?

答案 2 :(得分:1)

如果您真的在谈论卸载产品B时要恢复的数据文件(例如配置文件),我认为我们在安装A时会查看自定义操作备份A使用的数据。当卸载B时,它会从备份位置恢复数据。

无论哪种方式,问题似乎都是应用程序设计,其中A和B显然共享一些常见的数据文件集,只是它们只在安装时共享。

相关问题