我目前在使用根据此处的说明构建的MST在多实例方案中尝试使用MSP(也使用WiX构建)修补MSI(使用WiX构建)时遇到困难:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa367797(v=vs.85).aspx
我构建的转换工具:
安装应用了变换的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元素。
我不是100%肯定的,但我认为一些验证与基于两个图像的补丁的生成有关,而不是补丁应用程序本身(在旧学校中使用补丁的方式)来自PCP文件的MSIMSP)。如果修补程序转换生成中使用的两个图像没有相同的产品代码且ProductID验证设置为no,那么您将不会收到错误。否则,在修补程序生成期间会返回错误,告知您输入可能无效等等
答案 0 :(得分:0)
创建补丁涉及遵循多个规则,而不仅仅是匹配产品代码。以下MSDN文章详细介绍了这些规则:http://msdn.microsoft.com/en-us/library/aa367850.aspx
正如你在Yan Sklyarenko所链接的文章中所做的那样,同样的规则也在一开始就给他带来了问题。
答案 1 :(得分:0)
我设法让这个工作。由于各种原因,我们使用PatchCreation元素创建了原始补丁。以这种方式创建的转换是通过验证来设置的,该验证检查ProductCode和UpgradeCode。最后,我更新了我的转换以关闭它,而不是为每个转换更改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