У меня есть проект InstallShield 2012 Basic MSI, который я поддерживаю для нашей компании. Я не являюсь обученным разработчиком InstallShield (просто самый низкий [в то время] на тотемном столбе), но за эти месяцы я набрал достаточно, чтобы все работало гладко от версии к версии.
Недавно один из наших клиентов настоял на том, чтобы мы исправили ошибку в старой версии нашего продукта, которую мы уже исправили в новейшей версии. Обычно мы не создаем патчи, так как полный установщик работает как средство обновления, но в этом случае мы выполнили требования, создали ветку той версии, в которой они были, и отправили им патч обновления. В этот патч был включен только один файл, и он имел ту же версию, что и файл, который он заменял. Все было хорошо.
Сегодня этот клиент хочет перейти на нашу последнюю версию. По сути, мы объединяем их ветку обратно в основную ветку, и, поскольку в их ветке нет дополнительных компонентов или кода, специфичного для клиента, я подумал, что мы можем просто дать им наш обычный установщик, и он перезапишет все. Не так...
Когда я воспроизвел их разветвленную установку и попытался обновить файлы, программа установки успешно запустилась и заменила все, кроме их разветвленной dll. Возня с «omus», «amus», принудительная перезапись и т. д. ничего не меняет. Предварительное удаление файла ничего не дает. Что бы я ни пробовал, разветвленная dll остается, и лог выглядит примерно так (имена изменены для защиты виновных, версии и гуиды оставлены без изменений):
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 вручную, вместо того, чтобы использовать программу обновления, которую мы дали клиенту. Все обновилось правильно, поэтому сам файл не захлебывается)
Моя ближайшая цель — вернуть синхронизацию этого клиента, желательно без деинсталляции и с одним унифицированным установщиком вместо создания специального апдейтера только для них. Поскольку файлы уже находятся в дикой природе, если это невозможно, я могу переварить особый случай. Моя будущая цель состоит в том, чтобы заставить это работать естественно, как я и предполагал: файл является более старой версией, файл заменяется, все остальное не имеет значения.
Я думаю, что предоставил все необходимое, но если нет, я могу предоставить дополнительную информацию. Я провел большую часть сегодняшнего дня, глядя на это, и я просто не могу найти материала, похожего на этот сценарий.