WiX 3.0中的平台识别

14
我在将托管代码从x86迁移到x64平台时遇到了问题。我有一个WiX项目来创建MSI,该项目将通过Bootstrapper执行。
在x86平台上,文件按照Project.wxs文件中的方式复制到“Program Files”中。但是,如果通过Bootstrapper在x64平台上安装相同的MSI,则所有安装文件都会默认复制到“Program Files(x86)”中,并且应用程序的功能失败,因为它无法在Program Files的12-hive层次结构中找到所需的文件(对于64位系统,“C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\CONFIG”)。
我尝试使用预处理器变量,如<?if $(var.ProcessorArchitecture)=x64 ?> ,但我需要在项目属性中硬编码此变量为x86或x64。最终,我得到了两个不同的MSI,适用于两个不同的平台,这对我来说不是理想的解决方案。
因此,通过WiX,是否可以识别平台以确保在所需位置进行安装?
3个回答

21

我不相信您能够创建一个支持两个平台的单个MSI文件。您需要创建一个x86和一个x64的MSI文件,但好消息是您无需维护另一个WiX项目来实现这一点。

我过去处理这个问题的方法是在产品定义的开头添加以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

    <?if $(var.Platform)=x64 ?>
      <?define msiProductId = "102F7DF4-19A6-4d3d-987F-FF57A2031593" ?>
      <?define win64Flag = "yes" ?>
    <?else ?>
      <?define msiProductId = "8AE46CAF-220F-4B9F-9527-D4A19A27C45B" ?>
      <?define win64Flag = "no" ?>
    <?endif ?>

    <Product Id="$(var.msiProductId)"
             Name="My Product"
             Language="1033"
             Version="1.0.0"
             Manufacturer="Acme"
             UpgradeCode="E2575E4A-A62E-4460-B96D-B722C79C8EAA">

        <Package InstallerVersion="400"
                 Compressed="yes"
                 InstallPrivileges="elevated"
                 Platform="$(var.Platform)"
        />

        <!-- Rest of product definition goes here -->

    </Product>
</Wix>

我忘记了从哪里得到建议,要为每个平台使用不同的ProductID。

我创建了'win64Flag'变量,以便在跨平台情况下使其他WiX元素正常工作。这里是一个示例,演示如何使用它来使单个RegistrySearch定义适用于两个平台,并应该解决您在定位12-hive层次结构时遇到的问题。

<Property Id="WSE12DIRECTORY">
    <RegistrySearch Id="Reg_WSE12DIRECTORY"
                    Type="raw"
                    Root="HKLM"
                    Key="SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0"
                    Name="Location"
                    Win64="$(var.win64Flag)"
    />
</Property>

有了这些准备,只需在Candle命令行上为“ Platform”预处理器变量传递相关值,或在Visual Studio中选择目标平台即可。


3
在WiX 3中,不建议使用platform属性。他们建议将其省略,并改用candle的"-arch"开关。http://wix.sourceforge.net/manual-wix3/wix_xsd_package.htm - Chris
你可能需要使用sys.BUILDARCH而不是var.Platform。 - J. Polfer
据我所知,Windows Installer支持使用一个单一的MSI安装32位和64位组件。虽然MSI只能指定单个架构,但它可以嵌入32位和64位,并且Windows Installer能够通过一个安装过程同时安装两者。由于这些组件可能属于同一或不同的功能,因此有很多不同的设计空间。参考:https://learn.microsoft.com/en-us/windows/win32/msi/windows-installer-on-64-bit-operating-systems - Armen Michaeli

15

您可以使用条件语句(文档在这里),它将在安装时检测安装程序所运行的平台。这样,您就可以创建一个可在所有平台上运行的安装程序。

64位平台的测试为VersionNT64,非64位平台的测试相反,为NOT VersionNT64

例如:

<Component Id="SomeComponentId" Guid="SomeGuid">
    <Condition>
        <![CDATA[NOT(VersionNT64)]]>
    </Condition>
    <File Id="SomeFile" Name="Somefile.exe" Source="$(var.UI.TargetDir)\ProjectOutput.exe" />
</Component>

2
谢谢。现在这是WIX的另一个问题:通过WIX,当我访问其注册表键以获取64位组件的安装路径时,由于注册表重定向,它被重定向到WOW6432node,而那里不存在注册表键。因此,通过WIX,有没有办法只使用单个MSI创建来查看64位注册表视图?据我所知,必须将组件标记为Win64 =“yes”,才能导致将注册表条目写入64位注册表中心,而不是WOW64注册表中心。还有其他建议吗? - user223572
我的回答中提供了解决此问题的方案。 - JamesD
@PeterMortensen。是的。已修复。 - eh9

3

您可以使用

candle -arch x86 

或者
candle -arch x64 

因此,将生成Platform="x64"Win64="true"属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接