我的 WIX 项目有问题。当我进行正常的 GUI 安装时,一切都按预期工作。但是,当我执行/q(安静)安装时,我的目录 ID 符号之一没有被设置。 (可能是因为静默安装没有 UI 序列。但是,令我困惑的是我到底做错了什么。)
在我的 Product.wxs 中,我有一个这样开始的目录树:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="COMPANY" Name="Company">
<Directory Id="BRANCHALL" Name="Branch">
<Directory Id="INSTDIR" Name="Replaced">
<Directory Id="BINDIR" Name="Bin">
就在我设置目录的下面,因为我们的应用程序安装将安装 ID 作为用户输入字符串,它成为目录路径的一部分。 (它也可以在静默安装命令行中传递。)因此,就在上面的目录树定义下,我有:
<SetDirectory Id="INSTDIR" Value="[BRANCHALL]\[INSTID]" Sequence="execute" />
<SetDirectory Id="BINDIR" Value="[BRANCHALL]\[INSTID]\Bin" Sequence="execute" />
...等等
当我进行静默安装时,日志显示如下:
MSI (s) (F8:84) [20:55:29:702]: Product: ProductName - Instid -- Error 1606. Could not access network location \Instid.
Error 1606. Could not access network location \Instid.
Action ended 20:55:29: CostFinalize. Return value 3.
Action ended 20:55:29: INSTALL. Return value 3.
Property(S): UpgradeCode = {9AC2D8DF-5EF7-440B-A0D2-4A97FA62368C}
Property(S): INSTID = Instid
Property(S): BRANCHALL = C:\Program Files (x86)\Company\Branch\
Property(S): POWERSHELLEXE = C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
Property(S): BINDIR = \Instid\Bin
请注意,虽然记录的 BRANCHALL 值是正确的,但 BINDIR 符号缺少 BRANCHALL 值,但确实正确获取了 INSTID 值。
运行 GUI(非静默)安装时的相同日志片段:
Property(C): UpgradeCode = {9AC2D8DF-5EF7-440B-A0D2-4A97FA62368C}
Property(C): INSTID = Instid
Property(C): BRANCHALL = C:\Program Files (x86)\Company\Branch\
Property(C): POWERSHELLEXE = C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
Property(C): LicenseAccepted = 1
Property(C): BINDIR = C:\Program Files (x86)\Company\Branch\Replaced\Bin\
奇怪的是,BRANCHALL 属性进行了详细说明,而 INSTID 则没有。然而安装工作正常并将所有文件放在正确的文件夹中。所以INSTID一定是在msiexec做出这些日志后进行了详细说明。
如果缺少所需信息,请询问我。我有点困惑,当然不是 WIX 专家。谢谢!
最佳答案
要理解这一点,首先要意识到您的日志摘录是从末尾开始的,但它反射(reflect)了按特定顺序发生的各种操作。正如斯坦因在他的回答中提到的那样,SetDirectory elements您创作的是作为设置属性的自定义操作实现的。具体来说,<SetDirectory Id="INSTDIR" Value="[BRANCHALL]\[INSTID]" Sequence="execute" />
设置一个名为 INSTDIR
的属性到格式化的值 [BRANCHALL]\[INSTID]
在 CostFinalize 之前。
这是一个问题,因为在 CostFinalize 构建目录树之前,BRANCHALL
没有值(value)。显示 UI 时,CostFinalize 在每个序列中运行一次。第一个填充 BRANCHALL
,并为 INSTDIR
使用默认路径.第二个(执行)序列然后使用填充的 BRANCHALL
确定INSTDIR
,掩盖问题。但如果没有 UI,则使用空值。如果您搜索属性值更改的位置,您应该能够在详细日志中确认这一点。
那么解决办法是什么?至少在您的摘录中,您似乎可以预测 BRANCHALL
的默认值仅使用预定义的属性,因此应该能够相应地修改您的 SetDirectory 创作:
<SetDirectory Id="INSTDIR" Value="[ProgramFilesFolder]Company\Branch\[INSTID]" Sequence="execute" />
<SetDirectory Id="BINDIR" Value="[ProgramFilesFolder]Company\Branch\[INSTID]\Bin" Sequence="execute" />
但是,这样做有一个潜在的问题。如果您允许最终用户更改 BRANCHALL
中使用的任何位置在您的用户界面中,这将覆盖它。如果这种情况对您很重要,我相信指定 Sequence="first"
而不是 Sequence="execute"
将解决这个问题。 (但是你必须运行一些测试来确定这有帮助。)此外,对于希望覆盖它的静默安装,你可能需要记录一组更完整的必须指定的属性以及如何指定它们。因此,您可能需要按照 Not INSTDIR
的行向此 SetDirectory 元素添加一些条件。/Not BINDIR
或 Not I_CHANGED_THE_DIRECTORIES.
如果可能的话,我会推荐一种不同的方法:将 INSTID
的值放入在目录表中,而不是使用自定义操作来覆盖不正确的操作。主要的缺点是这需要创建并使用转换来设置它,而不是仅仅在命令行上传递一个值。但好处是 Windows Installer 只会像往常一样处理目录。
关于未为静默安装设置 Wix 目录 ID 符号值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50652655/