Инициировать удаление приложения с пониженной версией из кода управляемого загрузчика

Пользователи нашего установщика управляемого загрузчика должны иметь возможность понизить версию пакета, если новая версия вызывает проблемы:

<MajorUpgrade Schedule="afterInstallValidate" AllowDowngrades="yes" AllowSameVersionUpgrades="no" />

При обновлении существующий пакет корректно удаляется. Только новая версия остается в списке установленных программ в разделе Программы и компоненты. Журнал подтверждает выбранное действие:

OnDetectRelatedBundle(): Operation MajorUpgrade
OnDetectRelatedBundle(): RelationType Upgrade
Planned package: APP_MSI_PACKAGE, state: Absent, default requested: Present, ba requested: Present, execute: Install, …
Planned related bundle: { }, type: Upgrade, … execute: Uninstall, rollback: Install, dependency: None

При переходе на более раннюю версию существующий пакет остается в разделе Программы и компоненты. По логу тип downgrade распознан, но Uninstall не планируется:

OnDetectRelatedBundle(): Operation Downgrade
OnDetectRelatedBundle(): RelationType Upgrade
Planned package: APP_MSI_PACKAGE, state: Obsolete, default requested: None, ba requested: None, execute: None, …
Planned related bundle: {}, type: Upgrade … execute: None, rollback: None, dependency: None

В разделе Программы и компоненты не должно быть двух записей для одного и того же приложения. После понижения я могу удалить устаревшую версию вручную, но пользователь не должен этого делать.

Меня смущает, что MajorUpgrade является частью <Product>, но тогда в Программах и компонентах версия отслеживается для всего пакета. Я где-то читал, что один и тот же UpgradeCode должен использоваться в Product и Bundle. Это рекомендуется? Я пробовал один и тот же UpgradeCode и отдельные UpgradeCode. Кажется, нет никакой разницы.

Я немного исследовал, и предположительно удаление не поддерживается при понижении версии. Это правда? Если он не поддерживается, как я могу инициировать удаление соответствующего пакета вручную из кода управляемого загрузчика?

На самом деле проблема сводится к двойной записи в Программы и компоненты. Если я не могу удалить его, могу ли я удалить (или, может быть, скрыть, что я бы назвал ужасным взломом) устаревшую версию пакета с помощью кода каким-либо другим способом?


person Christian    schedule 11.03.2021    source источник


Ответы (1)


Мне нужно было определить, устанавливает ли программа установки более раннюю версию, используя событие DetectRelatedBundle. Затем в обработчике события для PlanRelatedBundle пришлось указать, что связанный бандл должен отсутствовать:

private void OnPlanRelatedBundle(object sender, PlanRelatedBundleEventArgs e)
{
    if (BundleUpgrade || BundleDowngrade)
        e.State = RequestState.Absent;
}

На всякий случай я также установил состояние отсутствия при обнаружении обновления, хотя этот случай уже работал. Теперь соответствующий пакет удаляется в обоих случаях.

person Christian    schedule 18.03.2021