2011-12-13 88 views
3

这需要一些解释,但在这里。多实例MSI包升级失败

我需要创建一个安装动态实例的多实例MSI - 即在用户安装包时定义的实例,而不是在MSI文件中进行硬编码。现在,我已经经历了创建引导程序和使用MSI API动态创建转换(MST)并将其应用于原始MSI的痛苦;经过多次修补,安装和卸载工作正常(我会张贴细节,因为他们需要)。

基本上,MST包含用于ProductCode,ProductName,PackageCode(在摘要信息中)的变换,更改所有组件的GUID(否则将以愚蠢的方式卸载失败),并且引导程序保护安装位置免受冲突。此外,引导程序将使用命令行参数MSINEWINSTANCE = 1开始安装,详见here

但是,我还想升级已安装的实例(通过主要升级),这是UpgradeCode独特(或者我认为)的主要原因。但是,在我增加MSI版本并尝试启动它(再次通过引导程序并通过MSIINSTANCEGUID属性传递所需实例的ProductCode)后,它将失败;日志说:

=== Verbose logging started: 12/13/2011 17:43:56 Build type: SHIP UNICODE 5.00.7601.00 Calling process: C:\Windows\SysWOW64\msiexec.exe === 
MSI (c) (5C:D0) [17:43:56:120]: Font created. Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg 

MSI (c) (5C:D0) [17:43:56:120]: Font created. Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg 

MSI (c) (5C:34) [17:43:56:120]: Resetting cached policy values 
MSI (c) (5C:34) [17:43:56:120]: Machine policy value 'Debug' is 2 
MSI (c) (5C:34) [17:43:56:120]: ******* RunEngine: 
      ******* Product: D:\TestArea\AMLDC.msi 
      ******* Action: 
      ******* CommandLine: ********** 
MSI (c) (5C:34) [17:43:56:120]: Machine policy value 'DisableUserInstalls' is 0 
MSI (c) (5C:34) [17:43:56:135]: MainEngineThread is returning 1625 
=== Verbose logging stopped: 12/13/2011 17:43:56 === 

和一个用户界面消息弹出说'系统管理员已设置策略,以防止这种安装'。显然这不是真的(策略会出现在日志中,并且会提供更明确的消息)。

1625错误代码似乎对应于“ERROR_INSTALL_PACKAGE_REJECTED”。

任何想法,我可以尝试未来?我想在这种情况下MSI引擎应该尝试做什么是检查UpgradeCode,应用原始转换(应该通过MSIINSTANCEGUID参数通过产品代码缓存和可达)。然而很显然,引擎永远不会到达这个阶段(它应该被记录在日志文件中,对吧?)

叹了口气,这已经比本应该更痛苦了。

编辑:一段时间后......不断变化的组件GUID

快速注:这是对非文件组件(我有我用它来跟踪实例的一些注册表项)只有确有必要。如果我不更改它们的GUID,则它们在卸载时没有被正确清理,详情如下here。对于文件,如果关键路径不同,它可以正常工作,而且我只通过更改我的代码中的注册表组件来验证文件。

因此,我在此期间了解到,除非我为每个实例更改UpgradeCode,否则主要升级可能不适用于我(因为FindRelatedProducts仅查看UpgradeCode,我认为),而且在尝试其他方法之前那里:小升级。

使用/ fvamus和MSIINSTANCEGUID = {existing-instance-product-code}一起启动新版本的安装程序似乎可以正常工作,直到我试图向包中添加一个新文件(我期望将来会发生)...当然它不起作用(当然,新文件的组件不会在重新安装时安装)。

因此,我可能需要通过转换来更改UpgradeCode,并查看含义,或者通过一些自定义操作来解决FindRelatedProducts的输出属性,并查看是否可以说服主要升级以这种方式工作。然而,最初的问题(1625错误)恰恰是主要的升级,所以不知道如果我不知道原因,我可以做些什么。要完全清楚:我上面所粘贴的是MSI详细日志的整体,但在返回错误1625之前似乎没有做任何事情。我也尝试删除MSI升级表中的所有行行为没有变化。

我也不能在这个愚蠢的问题上花费更多的时间,所以如果没有其他工作,我会被迫做一个静默卸载,然后用相同的设置进行常规安装。我对这个想法感到畏惧,但如果它不能帮助...

编辑:公平地说,如果我没有完全从MSI路径开始并编写我自己的安装程序,它可能会更快从头开始,使用gzipped流和简单的xcopy。即使有一个msbuild任务可以从visual studio或其他东西压缩文件。

+0

您是否在使用FindRelatedProducts/RemoveExistingProducts时遇到问题,或者是否安装了较新的版本,这些版本将作为主要升级的一部分删除之前的版本?当机器上有3个v1.0实例并且您尝试安装v2.0(主要升级)时,您希望发生什么?更改所有组件代码对我来说听起来并不常见,但我大多数人都认为它听起来不像当前症状的来源。 – 2011-12-17 15:54:34

+0

安装新版本时,我允许通过引导程序选择现有实例;我希望只有这个实例才能升级,因为我将它传递给了MSIINSTANCEGUID。然而,我从那以后就知道FindRelatedProducts只查看UpgradeCode,直到现在我对所有实例都保持相同。我已经尝试了小升级(通过用/ fvamus重新安装,这很适合我),并且它可以工作到一定程度。其实你知道什么,我会用所有这些新信息编辑问题。 – 2011-12-18 13:44:55

回答

0

这已经在这里坐了很长一段时间,所以我想我会关闭它。我最终的方式是卸载以前的实例,然后进行正常安装。似乎很好,所有的事情都考虑在内;完成工作。

0

难道你不能让你的实例作为功能吗?然后,他们将在安装过程中进行选择,升级与他们一起工作良好。甚至有特殊的动作“MigrateFeatureStates”用于加载已经安装的状态。

至于拒绝清除的组件 - 可能需要明确指定persistent =“no”吗?然后在卸载过程中必须将其移除。

+0

有趣的想法,但我觉得动态创建功能会有点太多的工作。至于没有正确清除的组件,我的意思是,如果它们共享相同的GUID,即使它们不是相同的“对象”(对于非注册表项等非文件组件),它们也会被视为共享,所以没有帮助不幸。 – 2011-12-23 08:19:20