1

我目前很难尝试使用根据此处的说明构建的 MST 在多实例场景中使用 MSP(也使用 WiX 构建)修补 MSI(使用 WiX 构建):

http://msdn.microsoft.com/en-us/library/windows/desktop/aa367797(v=vs.85).aspx

我构建的转换工具:

  • 生成新的 UpgradeCode/ProductCode 属性
  • 更新 Upgrade 表以使用新的 UpgradeCode
  • 更新 ProductName 属性以包含实例名称
  • 使用包含实例名称的新项目更新 ServiceControl 和 Shortcut 表
  • 更新 Directory 表以更新包含 INSTALLDIR 行的实例名称的 DefaultDir 列
  • 生成转换摘要信息并写入转换

安装应用了转换的 MSI 似乎可行。我这样调用 msiexec :

msiexec /i <product.msi> TRANSFORMS=<instance.mst> MSINEWINSTANCE=1

但是,修补似乎不起作用。我尝试按照此处所述应用补丁:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa369528(v=vs.85).aspx

msiexec /p <mypatch.msp> /n {product-code}

安装程序立即退出并显示“Windows Installer 服务无法安装升级补丁,因为要升级的程序可能丢失,或者升级补丁可能会更新程序的不同版本”。

基本 MSI 已安装,并且已在 WiX 中的 PatchCreation 元素上使用 AllowProductCodeMismatches="yes" 构建补丁。

如何获得要安装的补丁?


编辑:进一步阅读后,看起来我在做一些不好的事情。我现在已停止更改 UpgradeCode 属性,因为它似乎不需要,而且我自己工具的实例转换要轻得多。

我还查看了 @YanSklyarenko 的博客条目以进行修补 - 他修改了现有补丁以更改补丁适用的 ProductCode。我试过用类似的代码做同样的事情:

    // Copy original patch
    File.Copy(_patchPath, _newPatchPath, true);

    // Update patch target product code
    using (var patch = new PatchPackage(_patchPath))
    using (var patchForWrite = new Database(_newPatchPath, DatabaseOpenMode.Transact))
    {
        var originalProductCode = patch.GetTargetProductCodes().First();
        var productCode = _newProductCode;

        foreach (var transform in patch.GetTransforms())
        {
            // Extract/update transforms
            var tempFileName = Path.GetTempFileName();
            var transformFileName = transform + _instanceName;
            patch.ExtractTransform(transform, tempFileName);
            using (var summaryInfo = new SummaryInfo(tempFileName, true))
            {
                summaryInfo.RevisionNumber = summaryInfo.RevisionNumber.Replace(originalProductCode, productCodeString);
                summaryInfo.Persist();
            }

            // Write transform to new patch
            using (var insertView = patchForWrite.OpenView("INSERT INTO `_Storages` (`Name`,`Data`) VALUES ('{0}', ?)", transformFileName))
            {
                using (var record = new Record(1))
                {
                    record.SetStream(1, new FileStream(tempFileName, FileMode.Open));
                    insertView.Execute(record);
                    patchForWrite.Commit();
                }
            }

            // Add transform to patch properties
            patchForWrite.SummaryInfo.LastSavedBy += ";:" + transformFileName;
        }

        // Update patch properties
        patchForWrite.SummaryInfo.Template = patchForWrite.SummaryInfo.Template.Replace(originalProductCode, productCodeString);
        patchForWrite.SummaryInfo.Persist();
    }

我安装补丁仍然没有任何运气,并且 msiexec 在写入任何日志之前仍然退出。


编辑2:我仍然没有运气。我试过使用 WiX 实例转换来安装,但补丁仍然不适用。我的 PatchCreation 元素定义了每个实例的 TargetProductCode 元素,并且 AllowProductCodeMismatches 仍然打开。


编辑 3:听起来 AllowProductCodeMismatches 是一个 MSIMSP 东西,允许在两个不同的产品代码之间跳转以创建补丁而不是验证。目标产品代码必须包含在补丁中。不幸的是,对我来说 TargetProductCode 元素似乎被忽略了。

http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Re-Multiple-instance-patches-td1559146.html

我在这里不是一个 100% 肯定的人,但我认为一些验证与基于两个图像的补丁生成有关,而不是补丁应用程序本身(以老式的方式使用 PCP 的 MSIMSP 生成补丁)文件)。如果在补丁变换生成中使用的两个图像没有相同的产品代码并且 ProductID 验证设置为 no,那么您将不会收到错误。否则,在补丁生成过程中会返回一个错误,让您知道您的输入可能无效等

4

2 回答 2

1

我设法让这个工作。出于各种原因,我们的原始补丁是使用 PatchCreation 元素创建的。以这种方式创建的转换设置了检查 ProductCode 和 UpgradeCode 的验证。最后,我更新了我的转换以将其关闭,而不是更改每个转换的 ProductCode/UpgradeCode。因此,总而言之,将补丁应用于新产品代码:

  • 更新 Template SummaryInfo 属性并将原始 ProductCode 替换为实例 ProductCode
  • 提取转换并将其替换为禁用 ProductCode 和 UpgradeCode 验证的版本

然后安装补丁:

REM This works fine
msiexec /p <patch.msp> /n {<ProductCode>}

这对我不起作用- 我从日志中收到一条错误消息,指出 Windows Installer 无法创建补丁的临时副本。:

REM DON'T USE THIS!
msiexec /i {<ProductCode>} PATCH=<patch.msp>

编辑:要禁用的适当验证标志是:

PatchProduct =      0x00020000, // Disables product code matches
PatchUpgradeCode =  0x08000000, // Disables upgrade code matches
PatchMagic =        0x00040000, // Heck knows what this does - but Orca disables this
于 2013-02-19T17:26:18.353 回答
1

创建补丁涉及遵循多个规则,而不仅仅是匹配产品代码。以下 MSDN 文章更详细地解释了这些规则:http: //msdn.microsoft.com/en-us/library/aa367850.aspx

正如您在 Yan Sklyarenko 链接的文章中所看到的那样,同样的规则在开始时也给他带来了问题。

于 2013-02-12T09:29:43.163 回答