Пользовательское действие Wix для удаления старой версии, установленной с файлом INF

Я работаю над проектом, который использует WIX для установки приложения. Одно из требований — удалить старую версию перед установкой текущей. Старая версия не основана на MSI, она создана с помощью SetupApi (который опирается на файлы inf).

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

  1. найдите «древнюю» версию в HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\%NAME% и извлеките значение UninstallString, если возможно
  2. Если значение установлено, запустите пользовательское действие, которое выполнит эту команду, обычно это строка типа RunDll32 advpack.dll,LaunchINFSection C:\PROGRA~1\PROGRAM\file.inf, DefaultUninstall
  3. Это действие необходимо выполнить до установки программы, так как у них есть общие файлы и ключи реестра. Если пользовательское действие будет выполнено в конце установки MSI, это приведет к поломке программы.

Мои вопросы:

  1. Это рекомендуемый способ удаления старых программ на основе INF?
  2. Есть ли способ бесшумно удалить программы на основе INF? В противном случае пользовательский опыт будет довольно плохим — человек устанавливает программу и вдруг видит окно «удаление программы». Это противоречит здравому смыслу. [решается добавлением ",3" к команде удаления]

Если вам интересно, вот фрагменты кода, которые делают то, что я описал выше:

<Property Id="ANCIENTVERSION">
  <RegistrySearch Id="RegistrySearchAncientVersion" Type="raw"
     Root="HKLM" Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Program" 
     Name="UninstallString" />
</Property>

<CustomAction Id="removeAncientVersion"
        Directory="SystemFolder"
        <!--ExeCommand="[ANCIENTVERSION]"  regular uninstall-->
        ExeCommand="[ANCIENTVERSION],3" <!--silent uninstall-->
        Execute="immediate"
        Return="check"/>

<InstallExecuteSequence>
  <Custom Action='removeAncientVersion' After='InstallValidate'>ANCIENTVERSION</Custom>
</InstallExecuteSequence>

person ralien    schedule 30.01.2012    source источник
comment
Я думаю, вы можете сами создать приложение и вызывать функции SetupAPI с соответствующим INF. Таким образом, вы можете подавить пользовательский интерфейс прогресса по умолчанию. В качестве альтернативы вы можете показать пользователям диалоговое окно, в котором вы говорите, что будете удалять предыдущую версию приложения.   -  person Alexey Ivanov    schedule 01.02.2012
comment
Вызов функций SetupAPI напрямую является опцией, но, к сожалению, мне не удалось найти никаких подробностей о том, как выполнить автоматическую деинсталляцию с помощью SetupAPI. Есть обсуждения автоматической установки, но я не уверен, что это применимо к процессу удаления. Мои эксперименты пока не увенчались успехом.   -  person ralien    schedule 01.02.2012


Ответы (1)


После некоторых исследований я обнаружил, что для запуска автоматической деинсталляции нужно добавить «,3» в конец командной строки UninstallString. Я проверил это, и это работает:

Обычное удаление

RunDll32 advpack.dll,LaunchINFSection C:\PROGRA~1\PROGRAM\file.inf, DefaultUninstall

Автоматическое удаление

RunDll32 advpack.dll,LaunchINFSection C:\PROGRA~1\PROGRAM\file.inf, DefaultUninstall,3

Что касается первого вопроса - поскольку механизм удаления эквивалентен нажатию кнопки «Удалить» в программе «Установка и удаление», я считаю, что он не может быть чище/лучше.

person ralien    schedule 01.02.2012