How do I fix the upgrade logic of a wix setup after changing InstallScope to “perMachine”

谁说我不能喝 提交于 2019-12-28 13:21:23

问题


We use wix to create setups for our application. For the case where the user has already installed an older version of our application, we do a major upgrade with the MajorUpgrade XML element. This is all working as desired: if an older version is installed, it is upgraded transparently. If a newer version is present, the installer aborts with a clear message.

However, I now want to change the InstallScope from "perUser" to "perMachine". Unfortunately this breaks the upgrade logic. The new installer does not appear to detect and remove the previous "perUser" installation. Instead, it just installs itself on top of the older version in the same ProgramFiles location. The user gets to see two entries in the "add/remove programs" list and sees two identical shortcuts on the desktop (the old user-specific one and the new perMachine one).

How do I transition my installer from the "perUser" to the "perMachine" install scope without breaking the upgrade logic?


回答1:


Starting out with per-machine configuration.

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

This will run an automatic per-machine check (if you have the MajorUpgrade element working, I presume), that does not pick up the previous per-user install:

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...

So before install, make sure you run another FindRelatedProducts call for products that have been installed in user scope (e.g. like this):

<!-- 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>

This in turn finds the per-user install:

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}'.

Existing products will be removed no matter in which check they are found.

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

On a side note: This does not circumvent a basic difficulty that arises when you have dual-purpose installers: User1 on the machine might install in per-user scope, then later User2 installs per-machine. User1 will see both installs in his programs/features table, and I do not know which one takes precedence. So consider going with per-machine installs only.




回答2:


Sadly, the Windows Installer doesn't support that. Some process outside your package (a bootstrapper/chainer?) will have to manage the upgrade from per-user to per-machine.




回答3:


You can use this technique to detect per-user installation from per-machine install: http://www.mail-archive.com/wix-users@lists.sourceforge.net/msg35197.html




回答4:


This finds both existing perUser and/or perMachine installs. And forces the new install to a perMachine install (obviously logic to make that conditional could be applied as you wished). This works when run as an ordinary install and when installed silently under LocalSystem (silent upgrades). Keep in mind, it can only find a perUser install when running as that user.

Create a custom action (in DLL)

#pragma comment(linker, "/EXPORT:RunFindRelatedProducts=_RunFindRelatedProducts@4")
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

Then "replace" the standard FindRelatedProducts with the custom action

<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>


来源:https://stackoverflow.com/questions/678002/how-do-i-fix-the-upgrade-logic-of-a-wix-setup-after-changing-installscope-to-pe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!