Подтвердить что ты не робот

Как исправить логику обновления установки wix после изменения InstallScope на "perMachine"

Мы используем wix для создания настроек для нашего приложения. В случае, когда пользователь уже установил более старую версию нашего приложения, мы делаем крупное обновление с XML-элементом MajorUpgrade. Все это работает по желанию: если установлена ​​более старая версия, она прозрачно обновляется. Если присутствует более новая версия, программа установки прерывается с ясным сообщением.

Однако теперь я хочу изменить InstallScope с "perUser" на "perMachine". К сожалению, это нарушает логику обновления. Новый установщик не обнаруживает и не удаляет предыдущую установку "perUser". Вместо этого он просто устанавливает себя поверх старой версии в том же самом месте ProgramFiles. Пользователь получает две записи в списке "добавить/удалить программы" и видит два одинаковых ярлыка на рабочем столе (старый пользовательский и новый perMachine).

Как перевести мой установщик из "perUser" в область установки "perMachine", не нарушая логику обновления?

4b9b3361

Ответ 1

Запуск с конфигурацией для каждой машины.

<Property Id="ALLUSERS" Value="1" />

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

Action start 15:46:35: FindRelatedProducts.
MSI (c) (D0:0C) [15:46:35:496]: FindRelatedProducts: current install is per-machine.  Related install for product '{0C6604FB-58EC-48B9-8259-5871EFDADEB9}' is per-user.  Skipping...
MSI (c) (D0:0C) [15:46:35:496]: FindRelatedProducts: current install is per-machine.  Related install for product '{0C6604FB-58EC-48B9-8259-5871EFDADEB9}' is per-user.  Skipping...

Итак, перед установкой убедитесь, что вы запускаете другой вызов FindRelatedProducts для продуктов, которые были установлены в области пользователя (например, как это):

<!-- temporarily switch to per-user install scope-->   
<Publish Dialog="MyWelcomeDlg" Control="Next" Property="ALLUSERS" Value="{}">1</Publish>
<!-- find related products that have been installed per-user -->
<Publish Dialog="MyWelcomeDlg" Control="Next" Event="DoAction" Value="FindRelatedProducts">1</Publish>
<!-- switch back to per-machine install scope-->
<Publish Dialog="MyWelcomeDlg" Control="Next" Property="ALLUSERS" Value="1">1</Publish>

Это, в свою очередь, находит установку для каждого пользователя:

Action start 15:46:36: FindRelatedProducts.
FindRelatedProducts: Found application: {0C6604FB-58EC-48B9-8259-5871EFDADEB9}
MSI (c) (D0:88) [15:46:36:716]: PROPERTY CHANGE: Adding WIX_UPGRADE_DETECTED property. Its value is '{0C6604FB-58EC-48B9-8259-5871EFDADEB9}'.
MSI (c) (D0:88) [15:46:36:716]: PROPERTY CHANGE: Adding MIGRATE property. Its value is '{0C6604FB-58EC-48B9-8259-5871EFDADEB9}'.

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

Action start 15:46:41: RemoveExistingProducts.
RemoveExistingProducts: Application: {0C6604FB-58EC-48B9-8259-5871EFDADEB9}

Примечание. Это не обходит основную сложность, возникающую, когда у вас установлены двухцелевые инсталляторы: User1 на машине может устанавливаться в области для каждого пользователя, а затем User2 устанавливается для каждой машины. Пользователь1 увидит обе установки в своей таблице программ/функций, и я не знаю, какой из них имеет приоритет. Поэтому рассмотрите возможность установки только для каждой машины.

Ответ 2

К сожалению, установщик Windows не поддерживает это. Некоторый процесс за пределами вашего пакета (bootstrapper/chainer?) Должен будет управлять обновлением от каждого пользователя к каждой машине.

Ответ 4

Это находит как существующие установки perUser, так и/или perMachine. И заставляет новую установку устанавливать perMachine (очевидно, логика, чтобы сделать это условие применимым, как вы пожелаете). Это работает, когда запускается как обычная установка, и когда она устанавливается тихо в LocalSystem (тихие обновления). Имейте в виду, что он может найти только установку perUser при работе в качестве этого пользователя.

Создать пользовательское действие (в DLL)

#pragma comment(linker, "/EXPORT:[email protected]")
extern "C" __declspec(dllexport) UINT __stdcall RunFindRelatedProducts(MSIHANDLE a_hInstall)
{
MsiSetProperty(a_hInstall, "ALLUSERS", "1");
MsiDoAction(a_hInstall, "FindRelatedProducts");
MsiSetProperty(a_hInstall, "ALLUSERS", "");
MsiDoAction(a_hInstall, "FindRelatedProducts");
MsiSetProperty(a_hInstall, "ALLUSERS", "1");
return ERROR_SUCCESS;
}//end function

Затем "замените" стандартные FindRelatedProducts пользовательским действием

<InstallUISequence>
  <FindRelatedProducts>0</FindRelatedProducts>
  <Custom Action="RunFindRelatedProducts" Before='FindRelatedProducts'>NOT Installed</Custom>
</InstallUISequence>
<InstallExecuteSequence>
  <FindRelatedProducts>0</FindRelatedProducts>
  <Custom Action="RunFindRelatedProducts" Before='FindRelatedProducts'>NOT Installed</Custom>
</InstallExecuteSequence>