Файл понижения в MajorUpgrade
РЕДАКТИРОВАТЬ Пожалуйста, смотрите маленькое воспроизведение внизу.
У меня та же проблема, что и здесь: установщик Windows удаляет версионный файл во время обновления продукта, а не понижает его
File Table |File | Component_ | FileName | FileSize | Version|
-----------|--------------------------------------------------------------------------------------------------------------------------------------------
old MSI |fileEcMWtDjRdBXxvVHY.WvW_XXJI4GZcq5iAszC_F3KIwk | Cj9pc73bMjDSVVGUqS81_nPSltSFuUEweshtzct2AHi4 | bftlang.dll | 118784 | 2004.553.4453.1067
new MSI |fileYXlC3cFPRwh6qrJ5u..Ll052XUiMylAmA6a4BwMlz_o | CZJsalkL4nX.r6JS5xXH3pjmr9mY1AO4CITmUEHjP82I | bftlang.dll | 118784 | 2004.553.4453.1064
Component Table |Component | ComponentId | KeyPath
----------------|---------------------------------------------------------------------------------------------------------------------------------------
old MSI |Cj9pc73bMjDSVVGUqS81_nPSltSFuUEweshtzct2AHi4 | {C45097D5-E359-48B5-9F85-AB5EC81D62BF} | filepcu3NI3UMnsXucCthGSqTSHMvUoyVuyQHRbEXnUVii0
new MSI |CZJsalkL4nX.r6JS5xXH3pjmr9mY1AO4CITmUEHjP82I | {8B97BC16-7D4D-45CD-A3E3-903C60868202} | fileYXlC3cFPRwh6qrJ5u..Ll052XUiMylAmA6a4BwMlz_o
MSI (s) (88:A0) [20:12:50:115]: Disallowing installation of component: {8B97BC16-7D4D-45CD-A3E3-903C60868202} since the same component with higher versioned keyfile exists
(не по теме: поддерживает ли разметка Stackru таблицы? Они не упомянуты в справке.)
По какой-то причине наша система инкрементной сборки создает фиктивные номера версий, которые иногда уменьшаются. Хотя я бы согласился, если вы скажете мне сначала исправить это, это не под моим контролем, и та же проблема проявится, если кто-то захочет, например, отказаться от пакета nuget.
Обходной путь, упомянутый в связанном вопросе (планирование его перед калькуляцией), решает исходную проблему, но, похоже, вызывает проблемы с записью и обновлением.
Другой упомянутый обходной путь - это изменение REINSTALLMODE, но я использую Burn, который afaik не позволяет мне его менять. (У нас нет общих компонентов, поэтому, если бы можно было изменить REINSTALLMODE, это, вероятно, было бы лучшим решением.)
После составления расписания до Costing я несколько раз наблюдал проблему с тем, что загрузчик был зарегистрирован в ARP, но MSI не был установлен. (Я думаю, что это было вызвано отменой обновления, которое вызвало откат новой установки, но не переустановил старую версию - но я не уверен в этом).
Мы генерируем GUID компонентов, вызывая Guid.NewGuid(), поэтому правила компонентов нарушаются, поэтому я не могу запланировать это после InstallFinalize, но в комментарии упоминается, что MSI затем сохраняет старую (более высокую версию) версию, что, безусловно, не то, что Я хочу.
По сути, у меня есть макет каталога в моем MSI, и я хочу скопировать это 1:1 в выбранный каталог, игнорируя и перезаписывая любые существующие файлы независимо от их версии. Чтобы решить аналогичные проблемы с не версионными файлами, я использую этот шаблон для каждого файла:
<Component Directory="APPLICATIONFOLDER" Permanent="no" Guid="##Guid.NewGuid()##" Id="##some random id##">
<File Id="##some different random id##" Source="#source#" />
<RemoveFile Id='##some other random id##' On='install' Name='#name#'/>
</Component>
Если возможно, я бы хотел запланировать RemoveExistingProducts после InstallInitialize, чтобы удаление происходило внутри транзакции.
Есть ли чистый способ понизить версию файла во время серьезного обновления? Несмотря на то, что обходной путь планирования его до того, как стоить в основном работ, мне все равно пришлось подавить ICE27, который жаловался на это.
Редактировать:
Я искал немного больше и нашел этот вопрос, в котором упоминается изменение таблицы файлов после компиляции. Я думаю, что это может быть жизнеспособным вариантом для меня, но неужели так сложно обойти ошибку msi? (Я считаю серьезным обновлением удаление файла, а не его замену.)
EDIT2:
Я создал небольшое репро, оно содержит 6 файлов MSI:
- в with_different_guids версия DLL понижена, но обе версии имеют разные идентификаторы и разные идентификаторы GUID.
- в with_same_guids библиотека DLL также понижена, но обе версии имеют одинаковые (автоматически сгенерированные) ID и GUID.
Оба показывают одинаковое поведение:
Если я установлю 1\SetupProject.msi, каталог будет содержать три файла: 1 .txt, 1 .dll и 1.exe.
Если я затем запустлю 2\SetupProject.msi, будут переустановлены только.txt и.exe (версия.exe не изменится).
В rep_before_costinitialize REP планируется до CostInitialize, и MajorUpgrade работает, все три файла находятся на диске.
Edit3:
Я также смог воспроизвести мою проблему с ожогом:
Если я планирую REP до CostInitialize, MajorUpgrade работает как положено: DLL понижена.
НО транзакционная логика Burn Upgrade больше не работает, как ожидалось.
Если я устанавливаю файл setupExe \ 1 \ BootstrapperProject.exe, затем запускаю setupExe \ 2 \ BootstrapperProject.exe, но отменяю его посередине, ни MSI не установлен, но запись для 1 по-прежнему отображается в ARP.
1 ответ
FWIW, я говорил с поддержкой MS в прошлом о наличии REP, прежде чем платить, чтобы обновления работали успешно, и в то время они сказали, что все в порядке, отметив, что это также до MigrateExistingFeatures, так что если вы переносите функции во время обновлений там ' будет проблема.
Я бы не стал изменять таблицу файлов. Это гарантирует, что версия на диске не соответствует версии в таблице файлов, и делает файл кандидатом на восстановление. Если версия на диске - 2.0, а версия в таблице файлов - 3.0, исправление увидит, что файл поврежден. Некоторые крупные обновления или исправления заметят разницу и потребуют предоставить исходный MSI для восстановления файла (из-за несоответствия версий), прежде чем принимать решение о необходимости исправления или обновления файла. Windows не может знать, нуждается ли файл в обновлении входящим обновлением, если версия на диске не соответствует таблице файлов.
В любом случае для отдельного файла гораздо безопаснее и проще просто открыть darn-файл в Visual Studio и изменить реальную версию!
Есть также случайные ошибки, подобные этой https://support.microsoft.com/en-us/kb/905238 которые скрывают проблему.
Генерируете ли вы этот ключ таблицы файлов с помощью своего кода? Я подозреваю, что ваш ключ таблицы файлов отличается в разных MSI. Вероятно, это не проблема, но изменение ключей таблицы файлов, как известно, вызывает проблемы в других сценариях обновления. Если обновление пытается найти предыдущую версию файла, используя первичный ключ к таблице файлов (что делают реляционные базы данных), и не может найти ее в старом MSI, результаты могут быть непредсказуемыми.