了解具有多个实例

时间:2016-01-21 10:59:12

标签: wix windows-installer multiple-instances

我的多实例msi设置仅在我使用相同的msi文件时才有效。然后是用户

  • 可以更改目录
  • 安装新实例(如果是新目录)
  • 更新实例(如果它是现有目录)
  • 每个实例都有自己的卸载程序条目

如果我使用新版本的设置并运行更新,那么

  • 注册了具有相同显示名称的第二个卸载程序
  • 新设置中的第二个在维护模式下启动。没有 目录选择可能。其他实例的更新是 不可能。

阅读后关注博客文章 http://blogs.msdn.com/b/pusu/archive/2009/06/10/understanding-msi.aspx

我有PackageCode,ProductCode(每个实例)的硬编码 的UpgradeCode。它的工作方式与预期相符。但我收到了一个很大的警告 建造。我可以忽略这个吗?这是正确的解决方案吗?

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
    <Product Id="*" Language="1033" Manufacturer="i-net software GmbH" Name="i-net Test"
        UpgradeCode="02c7fa01-5143-38ed-b923-2c2aaff301ae" Version="8.0.0.507">
        <Package Comments="i-net Test Server" Compressed="yes" Id="c748d2f0-9ca5-3cbc-be9a-730c6d621f00"
            InstallScope="perUser" />
        <Media Cabinet="media1.cab" EmbedCab="yes" Id="1" />
        <InstanceTransforms Property="INSTANCE_ID">
            <Instance Id="Instance_0" ProductCode="c748d2f0-9ca5-3cbc-be9a-730c6d621f00" UpgradeCode="c748d2f0-9ca5-3cbc-be9a-730c6d621ff3" />
            <Instance Id="Instance_1" ProductCode="c748d2f0-9ca5-3cbc-be9a-730c6d621f01" UpgradeCode="4c8e1670-9d04-3dce-b88a-1a4dbbbc976d" />
            <Instance Id="Instance_2" ProductCode="c748d2f0-9ca5-3cbc-be9a-730c6d621f02" UpgradeCode="b76f160d-9395-3eda-a13d-d0566379ca8f" />
        </InstanceTransforms>
        <MajorUpgrade AllowDowngrades="yes" />
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="INSTALLDIR" Name="i-net Test" />
            </Directory>
        </Directory>
        <DirectoryRef Id="INSTALLDIR">
            <Directory Id="Server" Name="Server">
                <Component Guid="d62d7bcb-9242-39da-a43a-015df0f965af" Id="Server_Comp" MultiInstance="yes">
                    <CreateFolder />
                    <File Id="Server_testBuilds.jar" Name="testBuilds.jar" Source="..\testBuilds.jar" />
                </Component>
            </Directory>
            <Component Guid="1543477d-59fc-3ec3-bb67-a541abd9cfba" Id="instance_path" MultiInstance="yes">
                <RegistryKey ForceDeleteOnUninstall="yes" Id="instance_path_reg"
                    Key="Software\i-net software GmbH\i-net Test\Instances\[INSTANCE_NUMBER]" Root="HKLM">
                    <RegistryValue Type="string" Value="[INSTALLDIR]" />
                </RegistryKey>
            </Component>
        </DirectoryRef>
        <Property Id="INSTANCE_ID" Value="NotSet" />
        <Property Id="InstancesCount" Value="3" />
        <CustomAction Id="SetInstanceID" Script="vbscript">...</CustomAction>
        <InstallUISequence>
            <Custom Action="SetInstanceID" Before="ExecuteAction" />
            <Custom Action="SetTransforms" After="SetInstanceID">ACTION = "INSTALL"</Custom>
        </InstallUISequence>
        <InstallExecuteSequence>
            <Custom Action="SetInstanceID" Before="ValidateProductID" />
            <Custom Action="SetProductName" After="SetInstanceID">PRODUCT_NAME</Custom>
        </InstallExecuteSequence>
        <CustomAction Id="SetTransforms" Property="TRANSFORMS" Value="{:[INSTANCE_ID];}[TRANSFORMS]" />
        <CustomAction Id="SetProductName" Property="ProductName" Value="[PRODUCT_NAME]" />
        <Feature Id="MainApplication">
            <ComponentRef Id="Server_Comp" />
            <ComponentRef Id="instance_path" />
        </Feature>
    </Product>
</Wix>

您可以在https://github.com/i-net-software/SetupBuilder/blob/master/src/com/inet/gradle/setup/msi/MultiInstance.vbs

找到SetInstanceID操作

在使用之前&#34; *&#34;对于ProductCode(全局和每个实例)和 只硬编码了UpgradeCode(全局和每个实例)。

2 个答案:

答案 0 :(得分:1)

解决方案是错误的。必须为每个构建更改PackageCode和ProductCode。否则更新无效。这适用于单个实例,但也适用于多个msi文件实例。

多个实例的问题是MajorUpgrade element不适用于多个实例。如果使用Orca检查生成的msi文件,则只能看到Product Element中包含UpgradeCode的一个条目。您的实例中的UpgradeCodes不会在此表中侦听。要解决此问题,您必须手动将UpgradeCodes添加到此表:

<Property Id="InstancesCount" Value="3"/>
<InstanceTransforms Property="INSTANCE_ID">
  <Instance Id="Instance_0" ProductCode="*" UpgradeCode="GUID_0"/>
  <Instance Id="Instance_1" ProductCode="*" UpgradeCode="GUID_1"/>
  <Instance Id="Instance_2" ProductCode="*" UpgradeCode="GUID_2"/>
</InstanceTransforms>
<Upgrade Id="GUID_0">
  <UpgradeVersion MigrateFeatures="yes" Minimum="0.0.0.0" Property="WIX_UPGRADE_DETECTED_0"/>
</Upgrade>
<Upgrade Id="GUID_1">
  <UpgradeVersion MigrateFeatures="yes" Minimum="0.0.0.0" Property="WIX_UPGRADE_DETECTED_1"/>
</Upgrade>
<Upgrade Id="GUID_2">
  <UpgradeVersion MigrateFeatures="yes" Minimum="0.0.0.0" Property="WIX_UPGRADE_DETECTED_2"/>
</Upgrade>

如果您已移除MajorUpgrade element,则还必须添加:

<InstallExecuteSequence>
  <RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>

这只能添加一次,并会自动添加到MajorUpgrade中。更新表中的默认属性名称为WIX_UPGRADE_DETECTED。我们需要为每个实例使用单独的名称。我用&#34; _&#34;后缀了它。但也可能是其他所有。

如果我们使用Orca查看更新表,我们现在可以看到所有更新代码。但是有一个新问题。如果我们安装第二个实例,那么MSIEXEC会在FindRelatedProducts操作中找到其中一个UpgradeCodes的安装,并在RemoveExistingProducts中将其卸载。我们只能安装一个实例。之前的所有实例都已删除。

在FindRelatedProducts和RemoveExistingProducts之间,我们需要清除其他实例的WIX_UPGRADE_DETECTED_xx属性。只有当前实例的UpdateCode必须存在。我用一个小的vbscript动作做了这个:

<CustomAction Id="SetInstanceID" Script="vbscript">
InstancesCount = Session.Property( "InstancesCount" ) 
For i = 0 To InstancesCount - 1
    If CStr(i) &lt;&gt; instanceNumber Then
        Session.Property( "WIX_UPGRADE_DETECTED_" &amp; i ) = ""
    End If
Next
</CustomAction>

现在只有在RemoveExistingProducts中删除当前实例(如果已存在)。

答案 1 :(得分:0)

实际上,MajorUpgrade元素 可以处理多个实例。生成的实例转换将升级表的所有行替换为除UpgradeCode之外的相同的新行,UpgradeCode由该实例自己的UpgradeCode替换。如果从MSI中提取实例转换(使用SDK中的MsiDb.exe工具来提取与Instance / @ Id值相同的子存储,以便通过将它们应用于MSI来查看它们的实际效果在Orca)。