与其有条件地包含打开的Directory
元素(这会使XML无效),不如有条件地设置预处理器变量用作目录名称,正如@Daniel Pratt的评论所指。同样,根据平台设置一个“是/否”变量可以轻松设置64位组件、注册表搜索等。
定义变量
(来自此答案)
<?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位Program Files目录
<Directory Id="$(var.PlatformProgramFilesFolder)">
...
</Directory>
更新以处理单独的32/64位产品代码
回复rharrison33的评论,问如何处理在32位和64位安装程序中需要不同产品代码(或几乎任何内容)的要求(假设您不能/不想自动生成它们):
- 在命令行或使用响应文件时,将单独的产品代码作为预处理器变量传递给candle:
candle <所有其他标志> -d ProductCode32=<guid1> -d ProductCode64=<guid2>
- 将产品代码添加为与架构相关的预处理器变量之一,并将其设置为适当的输入变量:
- 在32位
<?if ?>
分支中:<?define ProductCode = "$(var.ProductCode32)" ?>
- 在64位
<?if ?>
分支中:<?define ProductCode = "$(var.ProductCode64)" ?>
- 在
Product/@Id
中引用$(var.ProductCode)
。
之所以将其设置为社区wiki是因为Daniel的链接回答了这个问题,而且除此之外还有更多很好的信息。