Используйте свойство Upgrade.
Предполагая
<Product Version="1.0.0.0" />
и
<Upgrade Id="GUID">
<UpgradeVersion OnlyDetect="no" Property="OLDERFOUND" Maximum="1.0.0.0" IncludeMaximum="no" />
<UpgradeVersion OnlyDetect='yes' Property='NEWERFOUND' Minimum="1.0.0.0" IncludeMinimum='no' />
<UpgradeVersion OnlyDetect='yes' Property='SAMEFOUND' Minimum="1.0.0.0" Maximum='1.0.0.0' />
</Upgrade>
Первая версия обновления находит все версии до текущей
вторая строка находит все версии выше текущей
третья строка находит установленные версии, совпадающие с текущей
Затем используйте настраиваемое действие, например
<CustomAction Id='NewerFound' Error='A later version of [ProductName] is already installed' />
<InstallExecuteSequence>
<Custom Action='NewerFound' After='FindRelatedProducts'>NEWERFOUND</Custom>
<RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>
и т.д.
Показанные настраиваемые действия либо удаляют старую версию автоматически, либо предупреждают пользователя о том, что более новая версия уже установлена, но если вы хотите запросить у пользователя информацию, вместо отображения ЦС вы можете показать свой пользовательский интерфейс.
Лично я просто использую первые две линии обновления. При этом выполняется автоматическое обновление, если найден более старый, отображается ошибка пользователя, если есть более новый, и, если установлен тот же, отображается ошибка пользователя (при этом по умолчанию не требуется третья строка). однако это не дает вам того пользовательского интерфейса, который вы хотите, поэтому, как я уже говорил выше, попробуйте заменить эти ЦС своим пользовательским интерфейсом.