user-interface - 如何创建允许在维护模式下运行时卸载特定实例的 MSI UI

标签 user-interface wix windows-installer multiple-instances wix3.6

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

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

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

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

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

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

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

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

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

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

编辑:

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

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

最佳答案

我在 http://www.codeproject.com/Articles/37825/WIX-SSRS-Custom-Assembly-Installer 找到的文章是让这项工作发挥最大作用的因素。

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

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

当按下“选择实例”对话框的“下一步”按钮时,将调用第二个自定义操作。这会将 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;

代码项目示例将选择实例对话框显示为弹出窗口,在准备序列中,因此它在 FindRelatedProducts 和 AppSearch 之前运行。也可以通过在 MaintenanceTypeDlg 中按返回来显示。但是,当尝试将其插入其他对话框序列时会出现问题,因此我将其设为普通的序列对话框,但它仍然有效。

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

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

关于user-interface - 如何创建允许在维护模式下运行时卸载特定实例的 MSI UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9398975/

相关文章:

java - 在没有 UiBinder 的情况下使用 GWT-Editors

javascript - jquery bubblepopup 在文本框上单击时出现

c# - WiX - 安装先决条件和第 3 方应用程序

WiX bundle 升级 : a new version of MSI is installed before the old version is removed

iis - 未选择 Web 功能时,如何禁用 Wix 中的 WebSite 操作?

installation - 是否可以根据属性使安装(MSI)的发布者(制造商)是动态的

user-interface - 用户界面图标

visual-studio-2010 - Wix HeatFile 任务锁 Dll

windows-installer - Windows 安装程序自定义操作错误 1631

c# - 快速显示/隐藏 WinForms GUI C# 的方法