使用 Wix 从一个 .wxs 文件创建 32 位和 64 位安装程序
我想在构建 32 位和 64 位安装程序时保持顶级 .wxs DRY。我使用 Candle.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 中尝试过此操作。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不是有条件地包含开始的
Directory
元素(这会使 XML 无效),而是有条件地设置用作目录名称的预处理器变量,如 @Daniel Pratt 的评论所指。同样,在平台上设置“是/否”变量可以轻松设置 64 位组件、注册表搜索等。定义变量
(来自 这个答案)
$(var.Platform)
是内置的,但它的值用于定义自定义变量$(var.ProductName)
、$(var.Win64)
和$(var.PlatformProgramFilesFolder)
。使用变量
您可以使用预处理器
指令来测试变量的值(就像在定义上面的自定义变量时使用
$(var.Platform)
所做的那样)或者让预处理器将变量的值插入到 XML 属性或元素值中。几个示例:32/64 位组件
这将在 Visual Studio WiX 编辑器中生成有关
$(var.Win64)
不是允许的属性值之一的警告 (yes/
no
),但可以安全地忽略这些,因为当编译器获取它时,预处理器将替换适当的值。32/64 位程序文件目录
更新以处理单独的 32/64 位产品代码
响应 rharrison33 的评论,询问如何处理 32 和 64 位安装程序中不同产品代码(或几乎任何内容)的要求(假设您可以) t/不想自动生成它们):
分支中:
分支中:
$ (var.ProductCode)
在Product/@Id
中。制作此 CW 是因为 Daniel 的链接回答了问题,并且还有更多重要信息。
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)
$(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
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
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):
<?if ?>
branch:<?define ProductCode = "$(var.ProductCode32)" ?>
<?if ?>
branch:<?define ProductCode = "$(var.ProductCode64)" ?>
$(var.ProductCode)
inProduct/@Id
.Made this CW because Daniel's link answers the question and has a lot more great info besides.
我在使用 WiX 3.7 时遇到了这个问题。这是一个很小的安装程序,我不需要变量的灵活性,因此我通过以与开始标签相同的方式包装它,从解析器中隐藏了结束目录标签:
...
这是一个黑客,但它适用于我的用例。
I had this problem with WiX 3.7. It was a tiny installer and I did not need the flexibility of variables so I hid the closing Directory tag from the parser by wrapping it in the same way as the opening tag:
...
It's a hack, but it worked for my use case.