将InstallScope更改为“perMachine”后,如何修复wix设置的升级逻辑

时间:2009-03-24 15:44:18

标签: installer wix windows-installer

我们使用wix为我们的应用程序创建设置。对于用户已安装旧版应用程序的情况,我们使用MajorUpgrade XML element进行重大升级。这一切都按预期工作:如果安装了旧版本,它将以透明方式升级。如果存在较新版本,则安装程序将以明确消息中止。

但是,我现在想将InstallScope从“perUser”更改为“perMachine”。不幸的是,这打破了升级逻辑。新安装程序似乎没有检测到并删除以前的“perUser”安装。相反,它只是在同一ProgramFiles位置的旧版本之上安装。用户可以在“添加/删除程序”列表中看到两个条目,并在桌面上看到两个相同的快捷方式(旧的用户特定的快捷方式和新的perMachine快捷方式)。

如何在不破坏升级逻辑的情况下将安装程序从“perUser”转换到“perMachine”安装范围?

5 个答案:

答案 0 :(得分:7)

可悲的是,Windows Installer不支持这一点。你的软件包外面的一些进程(一个bootstrapper / chainer?)必须管理从每个用户到每台机器的升级。

答案 1 :(得分:5)

从每台机器配置开始。

<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会安装 - 机。 User1将在他的程序/功能表中看到这两个安装,我不知道哪个安装优先。因此,请考虑仅按机器安装。

答案 2 :(得分:1)

您可以使用此技术从每台计算机安装中检测每个用户的安装:http://www.mail-archive.com/wix-users@lists.sourceforge.net/msg35197.html

答案 3 :(得分:0)

这会找到现有的perUser和/或perMachine安装。并强制新安装到perMachine安装(显然,可以按照您的意愿应用该条件的逻辑)。这在普通安装运行时以及在LocalSystem(静默升级)下静默安装时有效。请记住,它只能在以该用户身份运行时找到perUser安装。

创建自定义操作(在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

然后&#34;替换&#34;具有自定义操作的标准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>

答案 4 :(得分:0)

我实现了Mike Fuchs的方法,尽管它在技术上可以正常工作(也可以按预期运行安装),但该程序并未在其他用户的APR中出现。

经过深思熟虑,这是有道理的,因为安装程序将如何知道所有每用户安装已被删除/更新为新的perMachine版本。