3

我们正在使用 WIX 3.6 为 Silverlight/WCF 应用程序创建安装程序。我们需要能够安装多个实例来提供例如“Live”、“Test”和“Demo”。每个实例必须能够运行不同的版本并独立升级。这允许在升级“Live”之前在“Test”中安装新版本。

我正在使用 InstanceTransforms 机制来切换 ProductCode 和 CustomActions 来切换最多 10 个实例的 UpgradeCode。

我还设法通过自定义 MaintenanceTypeDlg 来创建 UI,以允许在不使用命令行的情况下安装新实例。我设置了 MSINEWINSTANCE=1 和 TRANSFORMS=:Instance,其中 Instance 是我在 ExecuteInstall 之前无法在注册表中找到的第一个实例。

我还可以通过主要升级路径升级默认实例。添加/删除程序上的删除和修复选项也可以正常工作。

我遇到的问题是在维护对话框中创建用于升级、修复或删除特定实例的机制。

我创建了一个 ComboBox,它使用带有所有已安装实例的 id 和名称的 CustomAction 填充,但我找不到可靠地将这些信息从 InstallUISequence 传递到 InstallExecuteSequence 的方法。

我尝试指定 TRANSFORMS=:Instance 但服务器 MSI 删除了该属性。我尝试指定 MSIINSTANCEGUID={[SelectedGuid]},但服务器 MSI 抱怨它是对属性的无效使用,因为它不是多实例安装。

我设法使用带有 TRANSFORMS=:InstancetoUpgrade 的命令行工作的特定实例的升级安装,并将 UpgradeTable 设置的属性覆盖到正确的实例 ProductCode,但是它缓存了 TRANSFORMS,并且如果没有 TRANSFORMS=,则始终应用该转换在命令行中指定。TransformsSecure 政策已设置,但我们无法在客户网站上更改此政策。

我无法找到 MSI 或 WIX 的任何文档或示例,这些文档或示例显示了在 InstallUISequence 和 InstallExecuteSequence 之间设置的正确属性,以强制服务器升级、修复或删除 MSI 中默认实例以外的实例用户界面已启动。

如果有人设法使多实例 MSI 的这个或类似方面工作,请发布任何 CustomAction、Properties 等示例,或有关如何使其工作的提示。

编辑:

我已经设法通过设置属性获得新版本的 MSI 来升级特定实例: UPGRADEFOUND={PreviousInstanceGUID} TRANSFORMS=:Instance;

但是,如果我再次尝试运行 MSI 以升级差异实例 TRANSFORMS 已经设置为我刚刚升级的那个。我的 UI 无法区分 MSI 是被双击还是从脚本运行以升级/修复特定实例。在维护模式下运行时,MSI 似乎也忽略了切换到服务器时对 TRANSFORMS 属性的任何更改。我需要一种方法来处理在某些情况下它将处于维护模式和其他升级模式的事实。实际上,当在 UI 中选择差异实例时,我需要能够重新运行 FindRelatedProducts 和 AppSearch。

4

2 回答 2

2

我在http://www.codeproject.com/Articles/37825/WIX-SSRS-Custom-Assembly-Installer上找到的文章是对这项工作的最大帮助。

看起来我缺少的步骤是在升级和安装上设置 MSINEWINSTANCE=1。

代码项目示例使用自定义操作来确定已安装哪些实例,并使用结果填充自定义 MSI 表,以及使用实例填充 ListBox。这具有额外的好处,即不需要大量带有 RegSearch 元素的公共属性来查找已安装的实例。

当按下 Select Instance 对话框的 Next 按钮时,将调用第二个自定义操作。这会将 TRANSFORMS、Installed、MSINEWINSTANCE、NEWPRODUCTFOUND、UPGRADEFOUND 和 MIGRATE 设置为适当的值。它复制了 FindInstalledProducts 的一些功能。关键值是:

新实例:

session["TRANSFORMS"] = string.Format(":{0}", nextAvailableInstance);
session["Installed"] = "";                                  
session["MSINEWINSTANCE"] = "1";
session["NEWERPRODUCTFOUND"] = "";
session["UPGRADEFOUND"] = instance.ProductCode;
session["MIGRATE"] = instance.ProductCode;

相同版本(维护):

session["TRANSFORMS"] = string.Format(":{0}", selectedInstance);
session["Installed"] = "1";
session["NEWERPRODUCTFOUND"] = "";
session["UPGRADEFOUND"] = "";
session["MIGRATE"] = "";

已安装较新版本:(应该给出降级错误)

session["TRANSFORMS"] = string.Format(":{0}", selectedInstance);
session["Installed"] = "1";
session["NEWERPRODUCTFOUND"] = instance.ProductCode;
session["UPGRADEFOUND"] = "";
session["MIGRATE"] = "";

已安装旧版本:(升级)

session["Installed"] = "";
session["MSINEWINSTANCE"] = "1";
session["NEWERPRODUCTFOUND"] = "";
session["UPGRADEFOUND"] = instance.ProductCode;
session["MIGRATE"] = instance.ProductCode;

代码项目示例将 Select Instance Dialog 显示为一个弹出窗口,在 Prepare 序列中,因此它在 FindRelatedProducts 和 AppSearch 之前运行。它也可以通过从 MaintenanceTypeDlg 中按 Back 来显示。但是,在尝试将其插入到其他对话框序列中时会出现问题,因此我将其设置为普通的序列对话框,它仍然可以工作。

为了正常工作,需要为所有实例设置 TRANSFORMS,因此永远不会安装默认实例。需要为此创建一个与任何其他 ProductCode 不同的虚拟 ProductCode。我使用了 Wix "*" 约定。我有默认的 UpgradeCode 与第一个转换的升级代码相同,但这可能会有所不同,甚至可以省略它。

我还发现我需要使用带有特定实例的 UpradeCode 的 CustomAction 填充 UpgradeTable,以避免它尝试删除升级中的所有其他实例。

于 2012-02-27T13:24:37.797 回答
0

除非您禁止 ARP,否则每个实例都应该在添加/删除程序中获得自己的条目,并且当您单击更改时,将处于该实例 ProductCode 独有的维护模式。

我错过了什么吗?也许您正在抑制 (ARPSYSTEMCOMPONENT),并且您想编写一个为所有实例提供服务的 UI。如果是这样,那可以做到,但它会比一些问题更大。

于 2012-02-23T01:16:31.030 回答