我面临MSM(合并模块)的补丁程序(小升级)安装(更新)问题。我正在用texst.wxs创建MSI(test.MSI)。在text.wxs中引用app.msm文件(有一个文件夹应用程序,它包含了很多文件夹和文件。并且收获这个文件夹并制作app.msm)
以下是制作app.msm文件的步骤。
heat dir "app" -gg -sfrag -template:module -srd -ke -var var.source -out app.wxs
candle -dsource=app app.wxs
light app.wixobj
下面是test.wxs文件的片段
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
....
....
<Directory Id='Config' Name='Config'>
<Component Id='APP_CLIENT' Guid='*'>
<Component Id='Manual' Guid='*'>
<File Id='Manual' Name='Manual.pdf' DiskId='1' Source='Resources/Manual.pdf'
KeyPath='yes'>
<Shortcut Id="startmenuManual" Directory="ProgramMenuDir"
Name="Instruction Manual" Advertise="yes" />
</File>
</Component>
</Directory>
<Directory Id='exmp_REPO' Name='!(loc.Merge_FolderTitle)'>
<Merge Id="LocalRepository" Language="1033" SourceFile="app.msm" DiskId="1"/>
<Component Id='exmp_REPOSITORY' Guid='*'>
<CreateFolder/>
<RemoveFolder Id='exmp_REPO' On='uninstall' />
</Component>
</Directory>
<Feature Id='Complete' Display='expand' Level='1' ConfigurableDirectory='MYAPPPATH'>
<ComponentRef Id='Manual'/>
<ComponentRef Id='App_CLIENT'/>
<ComponentRef Id='exmp_REPOSITORY'/>
…
我可以使用app.msm(合并模块)对test.wxs进行重大升级。但无法成功安装补丁。补丁安装(更新)反映在"程序和功能"中的版本更改中,并显示在"查看已安装的更新"中。手动更改也反映在补丁更新中。但"app"(创建于app.msm并在test.wxs中引用)文件夹中的任何更改都没有反映出来。
我使用了两种方法来制作补丁,这两种方法在下面的URL 中有所介绍
1)http://wixtoolset.org/documentation/manual/v3/patching/patch_building.html
2)http://wixtoolset.org/documentation/manual/v3/patching/wix_patching.html
请在这方面提供帮助。
首先,我建议找出构建的补丁是否包含正确的文件。如果没有,则说明您有一个生成问题,即msm没有更新。如果是,则很可能是msm的内容有问题,可能与它的前代不一致(尤其是GUID、表主键等)。
您可以使用Orca和Insted等工具查找并查看修补程序的内容,而无需安装即可搜索和下载。
其次,使用合并模块是非常复杂的事情,尤其是对于补丁,如果它们是您自己的,并且您只使用过一次,则用处有限。msm主要用于以下情况,即您至少需要两个不同的MSI包使用.msm。顺便说一句,我在使用其他工具的补丁中使用合并模块时遇到了很多问题。我在WiX+补丁+MSM方面没有特别的经验,但正如我所说。
最后,但同样重要的是,如果你真的想在未来保持这种复杂性,你必须做出选择。正如我所记得的,WiX还有其他的可能性来模块化/封装你的软件的一部分。
您可以通过使用Orca打开合并模块和MSI文件并在File表中查找来检查它们的版本。或者用Orca打开MSI文件,然后Transform=>查看补丁以查看更改。
这可能是显而易见的,但二进制版本的文件将被文件版本更高的文件所取代。我之所以提到这一点,是因为有一种观点认为"新"文件会以某种方式取代"旧"文件,这是错误的。版本很重要。
通常,您需要安装一个带有msiexec命令的修补程序,该命令指定REINSTALL=ALL REINSTALLMODE=omus。双击MSP文件不一定只起作用,除非您已经安排它在内部执行此操作,并在设置PATCH时设置自定义操作。
如果您违反组件规则,修补程序将不起作用。一个常见的错误是在补丁过程中删除组件,这将导致"广告"更新实际上并没有更新任何内容。在详细日志中,不支持查找SELMGR条目和有关删除组件的文本。如果执行了此操作,则将MSIENFORCEUPGRAECOMPONENTRULES属性设置为1将使修补程序失败。
如果一个文件没有版本,它是否被覆盖取决于这里的替换规则,如果文件是否被哈希,则会有一些区别:
https://msdn.microsoft.com/en-us/library/aa370531(v=vs.85).aspx
还有:你怎么知道补丁不起作用?如果您没有文件版本,那么除非您仔细查看,否则您无法知道文件是否已被替换。您不能信任这些日期,因为Windows会在安装文件时更改时间戳。你真的需要用文件版本来构建二进制文件,因为补丁、修补程序、service Pack等都会使用它们来替换二进制文件。否则,对于数据文件,请使用文件哈希。
我在这里看到了几个潜在的问题,甚至可能除了其他答案之外:
- 当你为合并模块加热文件时,gg会自动生成新的组件指南。这将不适用于补丁,因为它基本上会添加一堆新组件(每次都添加新的guid!!)。此外,您将以这种方式删除组件,这是不应该做的事情,也不容易做到,除非您仍然包含原始合并模块。然后你会遇到路径问题
- wix补丁教程使用wixpdb文件来区分原始安装程序和更新的安装程序。对于wixpdb文件,合并模块将不会被修补,无论其中的文件是否发生了更改。您需要进行管理安装,然后对msi本身进行差异化。您仍然会遇到问题#1
- 你的wxs代码段不好。至少xml元素从未正确关闭。您的功能在某个地方也有MergeRef
一些提示:
- 你可以通过一个名为Orca的程序查看你的补丁程序。打开原始msi,然后将msp补丁文件拖到它上面
- 不要使用合并模块,因为它们会使事情复杂化。你也可以使用热量生成一个片段,然后简单地将其包含在你的wix项目中
- 使用wix修补方法(Patch元素,而不是PatchCreation元素)。这更容易,但你有同样的控制
- 如果您计划使用补丁更新那些自动生成的组件,请不要自动生成guid。重大升级不会有问题:)
只有一个重要问题,即文件未正确更新时的许多潜在原因:您在.msm中编写了大量未经转换的文件,如.xml等。
重要规则:
第一次安装MSI后,在电脑上更改的每个未经版本的文件(不是由MSI引擎本身更改的(例如,您编辑了config.xml文件左右),通常MSI不会再次更新,也不会通过补丁和主要升级进行更新。(通常情况下,我的意思是,您必须采取特殊操作,例如卸载或特别指定这些文件为所谓的配套文件)。