使用Wix从一个.wxs文件创建32位和64位安装程序

时间:2011-06-03 19:49:36

标签: wix 64-bit wix3

我想在构建32位和64位安装程序时保持我的顶级.wxs DRY。我正在使用candle.exe的-arch参数来控制构建默认安装程序架构。

我现在遇到的问题是,看起来ProgramFilesFolder在32位和64位(ProgramFiles64Folder)架构之间是不同的。这是我第一次尝试解决这个问题:

<?if $(sys.BUILDARCH)=x64 ?>
<Directory Id='ProgramFiles64Folder' Name='PFiles'>
<?else ?>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<?endif ?>
    <Directory Id='the-rest' Name="Company Name">
...

我尝试了这个错误。显然,在评估预处理器之前会触发XML验证。当我手动更改为使用ProgramFiles64Folder我的构建工作。

我试图沿着DirectoryRef路线走下去但没有成功。有关在没有在.wxs文件中进行sed替换的情况下使其工作的任何建议吗?

注意:我在Wix 3.5和3.6中试过这个。

2 个答案:

答案 0 :(得分:42)

而不是有条件地包括开始Directory元素(使XML无效),有条件地设置用作目录名称的预处理器变量,如@Daniel Pratt的评论所指。同样,在平台上设置“是/否”变量可以很容易地设置64位组件,注册表搜索等。

定义变量

(来自this answer

<?if $(var.Platform) = x64 ?>
  <?define ProductName = "Product Name (64 bit)" ?>
  <?define Win64 = "yes" ?>
  <?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?else ?>
  <?define ProductName = "Product Name" ?>
  <?define Win64 = "no" ?>
  <?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?endif ?>

$(var.Platform)是内置的,但其值用于定义自定义变量$(var.ProductName)$(var.Win64)$(var.PlatformProgramFilesFolder)

使用变量

您可以使用预处理器<?if指令来测试变量的值(在定义上面的自定义变量时使用$(var.Platform)完成)或让预处理器将变量的值插入XML属性或元素值。几个例子:

32/64位组件

<Component Id="..." Win64="$(var.Win64)">
   ...
</Component>

这将在Visual Studio WiX编辑器中产生警告,其中$(var.Win64)不是允许的属性值之一(yes / no),但可以安全地忽略这些警告,因为预处理器在编译器获取它时,它将替换一个适当的值。

32/64位程序文件目录

<Directory Id="$(var.PlatformProgramFilesFolder)">
  ...
</Directory>

更新以处理单独的32/64位产品代码

回应rharrison33的评论,询问如何处理32位和64位安装程序中不同产品代码(或几乎任何东西)的要求(假设您不能/不想自动生成它们):< / p>

  • 在命令行上或使用响应文件将单独的产品代码作为预处理程序变量传递给candle:
candle <all other flags> -d ProductCode32=<guid1> -d ProductCode64=<guid2>
  • 将产品代码添加为依赖于体系结构的预处理器变量之一,并将其​​设置为适当的输入变量:
    • 在32位<?if ?>分支中:<?define ProductCode = "$(var.ProductCode32)" ?>
    • 在64位<?if ?>分支中:<?define ProductCode = "$(var.ProductCode64)" ?>
  • 请参阅$(var.ProductCode)中的Product/@Id

制作这个CW因为Daniel的链接回答了这个问题并且还有很多很好的信息。

答案 1 :(得分:3)

我在使用WiX 3.7时遇到了这个问题。这是一个很小的安装程序,我不需要变量的灵活性,所以我通过以与开始标记相同的方式包装它来解析关闭的Directory标记:

<?if $(sys.BUILDARCH)=x64?>
    <Directory Id="ProgramFiles64Folder">
<?else?>
    <Directory Id="ProgramFilesFolder">
<?endif?>

...

<?if $(sys.BUILDARCH)=x64?></Directory><?else?></Directory><?endif?>

这是一个黑客,但它适用于我的用例。