使用 Wix 从一个 .wxs 文件创建 32 位和 64 位安装程序 [英] Using Wix to create 32bit and 64bit installers from one .wxs file

查看:53
本文介绍了使用 Wix 从一个 .wxs 文件创建 32 位和 64 位安装程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

<Directory Id='ProgramFiles64Folder' Name='PFiles'><?否则吗?><Directory Id='ProgramFilesFolder' Name='PFiles'><?endif ?><Directory Id='the-rest' Name="公司名称">...

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

我尝试使用 DirectoryRef 路由但没有成功.关于在 .wxs 文件中不进行 sed 替换的情况下使其正常工作的任何建议?

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

解决方案

与其有条件地包含开始的 Directory 元素(使 XML 无效),不如有条件地设置用作目录名称的预处理器变量,正如@Daniel Pratt 的评论所指.同样,以平台为条件的是/否"变量可以轻松设置 64 位组件、注册表搜索等.

定义变量

(来自这个答案)

<?define ProductName = "产品名称(64 位)" ?><?define Win64 = "yes" ?><?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?><?否则吗?><?define ProductName = "产品名称" ?><?define Win64 = "no" ?><?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?><?endif ?>

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

使用变量

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

32/64 位组件

...</组件>

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

32/64 位程序文件目录

...</目录>

<小时>

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

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

  • 在命令行或使用响应文件将单独的产品代码作为预处理器变量传递给蜡烛:
<前>蜡烛 <所有其他标志> -d ProductCode32= -d ProductCode64=

  • 添加产品代码作为依赖于体系结构的预处理器变量之一,并将其​​设置为适当的输入变量:
    • 在 32 位 分支中:
    • 在 64 位 分支中:
  • 参考Product/@Id中的$(var.ProductCode).
<小时>

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

I would like to keep my top level .wxs DRY while building 32 and 64 bit installers. I am using the -arch argument to candle.exe to control what default installer architecture is getting built.

The wall I am hitting right now is that it appears the ProgramFilesFolder is different between 32 and 64bit (ProgramFiles64Folder) architectures. Here is my first attempt to work around:

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

I tried this with an error. Apparently the XML validation is fired before the preprocessor is evaluated. When I manually change to use ProgramFiles64Folder my build works.

I tried to go down the DirectoryRef route without success. Any suggestions on getting this to work without doing a sed replace within the .wxs file?

Note: I tried this in Wix 3.5 and 3.6.

解决方案

Rather than conditionally including the opening Directory elements (which invalidates the XML), conditionally set preprocessor variables which are used as directory names, as @Daniel Pratt's comment refers to. Similarly, having a "yes/no" variable conditioned on platform makes it easy to set up 64 bit components, registry searches, etc.

Defining the variables

(From 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) is built-in, but its value is used to define custom variables $(var.ProductName), $(var.Win64) and $(var.PlatformProgramFilesFolder).

Using the variables

You can either use preprocessor <?if directives to test variables' values (as is done with $(var.Platform) when defining the custom variables above) or have the preprocessor insert variables' values into XML attribute or element values. Couple of examples:

32/64-bit components

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

This will produce warnings in the Visual Studio WiX editor about $(var.Win64) not being one of the allowable attribute values (yes/no) but these can be safely ignored, because the preprocessor will have substituted an appropriate value by the time the compiler gets hold of it.

32/64 bit Program Files directory

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


Update to handle separate 32/64 bit product codes

In response to rharrison33's comment asking how to handle the requirement for different product codes (or pretty much anything) in the 32 and 64 bit installers (assuming you can't/don't want to auto-generate them):

  • Pass separate product codes to candle as preprocessor variables, on the command line or using a response file:

candle <all other flags> -d ProductCode32=<guid1> -d ProductCode64=<guid2>

  • Add a product code as one of your architecture-dependent preprocessor variables, and set it to the appropriate input variable:
    • In the 32-bit <?if ?> branch: <?define ProductCode = "$(var.ProductCode32)" ?>
    • In the 64-bit <?if ?> branch: <?define ProductCode = "$(var.ProductCode64)" ?>
  • Refer to $(var.ProductCode) in Product/@Id.

Made this CW because Daniel's link answers the question and has a lot more great info besides.

这篇关于使用 Wix 从一个 .wxs 文件创建 32 位和 64 位安装程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆