我有一个我一直在为我们公司维护的 InstallShield 2012 Basic MSI 项目。我不是一个训练有素的 InstallShield 开发人员(只是 [当时] 图腾柱上最低的),但我在这几个月里学到了足够多的东西来让每个版本都能顺利运行。
最近,我们的一位客户坚持要我们修复旧版本产品中的错误,我们已经在最新版本中修复了该错误。我们通常不创建补丁,因为完整的安装程序兼作更新程序,但在这种情况下,我们遵守了,在他们所在的版本上创建了一个分支,并向他们发送了一个更新补丁。该补丁中仅包含一个文件,并且它与要替换的文件具有相同的版本。一切都好。
今天,该客户希望升级到我们的最新版本。实际上,我们正在将他们的分支合并回主线,并且由于他们的分支没有额外的组件或特定于客户端的代码,我认为我们可以简单地给他们我们的常规安装程序并让它覆盖所有内容。不是这样...
当我复制他们的分支安装并尝试更新文件时,安装程序成功运行并替换了除分支 dll 之外的所有内容。修补“omus”、“amus”、强制覆盖等不会改变任何事情。事先删除文件没有任何作用。无论我尝试什么,分支的 dll 仍然存在,日志看起来像这样(更改名称以保护有罪者,版本和 guid 保持不变):
正确更新的 DLL:
Executing op: RegisterSharedComponentProvider(,,File=dll_that_works.r1,Component={B4F132E0-6C2A-4138-990B-16B991F8C54D},ComponentVersion=1.1.1.195,ProductCode={B2F1D6AC-95A4-44A9-9A52-631A3AD14389},ProductVersion=1.1.1,PatchSize=0,PatchAttributes=0,PatchSequence=0,SharedComponent=0,IsFullFile=0)
Executing op: FileCopy(SourceName=SY2F9C~1.DLL|dll_that_works.dll,SourceCabKey=dll_that_works.r1,DestName=dll_that_works.dll,Attributes=16384,FileSize=51584,PerTick=65536,,VerifyMedia=1,,,,,CheckCRC=0,Version=1.1.1.195,Language=0,InstallMode=130023424,,,,,,,)
File: C:\inetpub\wwwroot\Service\bin\dll_that_works.dll; Overwrite; Won't patch; REINSTALLMODE specifies all files to be overwritten
Source for file 'dll_that_works.r1' is compressed
不更新的分支 DLL:
Executing op: SetSourceFolder(Folder=C:\Windows\Installer\$PatchCache$\Managed\CA6D1F2B4A599A44A92536A1A31D3498\1.1.1)
Executing op: RegisterSharedComponentProvider(PatchGUID={EC6657A6-01A1-4AFC-86F9-1F4BF5F15481},MediaCabinet=#PCW_CAB_Family1,File=branched_dll.r,Component={74531F91-82A9-421D-A227-15DDDEDFC2FA},ComponentVersion=1.1.1.195,ProductCode={B2F1D6AC-95A4-44A9-9A52-631A3AD14389},ProductVersion=1.1.1,PatchSize=35952,PatchAttributes=0,PatchSequence=10000,SharedComponent=0,IsFullFile=0)
Executing op: FileCopy(SourceName=branched_dll.r,SourceCabKey=branched_dll.r,DestName=branched_dll.dll,Attributes=0,FileSize=225664,PerTick=65536,,VerifyMedia=0,,TotalPatches=1,,,CheckCRC=0,Version=1.1.1.195,Language=0,InstallMode=130023424,,,,,,,)
File: C:\inetpub\wwwroot\Service\bin\branched_dll.dll; Overwrite; Smart patch; REINSTALLMODE specifies all files to be overwritten
Redirecting file copy of 'C:\inetpub\wwwroot\Service\bin\branched_dll.dll' to 'C:\Config.Msi\PTB2C9.tmp'. A subsequent patch will update the intermediate file, and then copy over the original.
Source for file 'branched_dll.r' is uncompressed, at 'C:\Windows\Installer\$PatchCache$\Managed\CA6D1F2B4A599A44A92536A1A31D3498\1.1.1\'.
这有点超出我的深度。据我所知,它正在尝试修补分支的 DLL,但不能这样做,并且出于某种原因将文件扔到临时目录中(我找不到有关“智能补丁”究竟是什么意思的详细信息)。我已经看到应用到错误版本的补丁会发生这种情况,但这不是补丁!这是一个使用 REINSTALLMODE=v(oa)mus 和 REINSTALL=ALL 运行的常规安装程序。它应该只看到旧版本,看到它嵌入了新版本,然后将旧版本吹走。
(一时兴起,我尝试手动更新 DLL,而不是使用我们为客户端提供的更新程序。一切都正确更新,因此文件本身不会阻塞)
我的直接目标是让这个客户端重新同步,最好不用任何卸载并使用一个统一的安装程序,而不是为他们创建一个特殊的更新程序。由于文件已经在野外,如果这不可行,我可以忍受一个特殊情况。我未来的目标是让它像我想象的那样自然地工作——文件是旧版本,文件被替换,其他都不重要。
我想我已经提供了所有相关的信息,但如果没有,我可以提供更多信息。我今天大部分时间都在看这个,我根本找不到任何与这种情况类似的材料。