【问题标题】:Using Wix to create 32bit and 64bit installers from one .wxs file使用 Wix 从一个 .wxs 文件创建 32 位和 64 位安装程序
【发布时间】:2011-09-08 02:02:33
【问题描述】:

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

我现在遇到的问题是,32 位和 64 位 (ProgramFiles64Folder) 架构之间的 ProgramFilesFolder 似乎有所不同。这是我第一次尝试解决方法:

<?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 中尝试过这个。

【问题讨论】:

标签: wix 64-bit wix3


【解决方案1】:

正如@Daniel Pratt 的评论所指的那样,有条件地设置用作目录名称的预处理器变量,而不是有条件地包含开头的Directory 元素(这会使XML 无效)。同样,以平台为条件的“是/否”变量可以轻松设置 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)

使用变量

您可以使用预处理器 &lt;?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 位安装程序中不同产品代码(或几乎任何东西)的要求(假设您不能/不想自动生成它们):

  • 在命令行或使用响应文件将单独的产品代码作为预处理器变量传递给蜡烛:
蜡烛 -d ProductCode32= -d ProductCode64=
  • 添加产品代码作为与架构相关的预处理器变量之一,并将其​​设置为适当的输入变量:
    • 在 32 位 &lt;?if ?&gt; 分支中:&lt;?define ProductCode = "$(var.ProductCode32)" ?&gt;
    • 在64位&lt;?if ?&gt;分支中:&lt;?define ProductCode = "$(var.ProductCode64)" ?&gt;
  • 请参阅Product/@Id 中的$(var.ProductCode)

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

【讨论】:

  • 这基本上就是我所做的。我现在在必要时包含了一个 config.wxi,它定义了用于平台的正确 Program Files 文件夹。
  • 但是如果您将此 msi 打包到刻录包中,这种方式会产生问题,因为要求产品代码在 x86 和 x64 版本之间必须不同。谁能提供解决方法?
  • @rharrison33 如果您不能简单地自动生成产品代码,请查看我的编辑。
  • @shambulator 效果很好!谢谢!
  • &lt;Component Id="..." Win64="$(var.Win64)"&gt;&lt;Component Id="..."&gt; 有何不同?默认值不是平台自动决定的吗?
【解决方案2】:

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

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

...

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

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

【讨论】:

  • 感谢分享,有助于了解问题的根本原因。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多