为什么我的WiX安装程序需要一个空的CreateFolder才能有条件地更新Xml文件?

50

TL;DR: 在这个条件组件中,为什么我需要一个<CreateFolder/> 空元素才能使其正常工作?

我正在为内部应用程序编写一个基于WiX的简单安装程序。该安装程序需要部署一个标准配置文件(普通的.NET .config文件),然后使用通过命令行传递给msiexec的属性进行自定义。

其中一个自定义项是仅在RUNTIME属性已被定义时创建特定的应用程序设置。以下是该选项的WiX组件:

  <Component Id="C.Rbnz.Fsis.CollectionPeriodService.exe.config.runtime"
             Guid="*">
    <Condition>
      <![CDATA[RUNTIME]]>
    </Condition>

    <CreateFolder/>

    <util:XmlFile Id="X.Runtime.1"
                  Action="createElement"
                  ElementPath="/configuration/appSettings"
                  File="[#F.Rbnz.Fsis.CollectionPeriodService.exe.config]"
                  Name="add"
                  Sequence="2"/>

    <util:XmlFile Id="X.Runtime.2"
                  File="[#F.Rbnz.Fsis.CollectionPeriodService.exe.config]"
                  ElementPath="/configuration/appSettings/add[\[]not(@key)[\]]"
                  Action="setValue"
                  Name="key"
                  Value="RunTime"
                  Sequence="3"/>

    <util:XmlFile Id="X.Runtime.3"
                  File="[#F.Rbnz.Fsis.CollectionPeriodService.exe.config]"
                  ElementPath="/configuration/appSettings/add[\[]@key='RunTime'[\]]"
                  Action="setValue"
                  Name="value"
                  Value="[RUNTIME]"
                  Sequence="4"/>

  </Component>

如果在msiexec的命令行中指定了RUNTIME,则会创建新元素,否则不会。

我为什么要在此组件中放置空的<CreateFolder/>元素?

在我试图让这个工作时,我发现了"Wix Condition Statement",它展示了一个有效的组件,但没有说明为什么需要<CreateFolder/>

移除<CreateFolder/>会导致ICE18错误:

ICE18:组件“C.Rbnz.Fsis.CollectionPeriodService.exe.config.runtime”的关键路径是目录:“INSTALLDIR”。目录/组件对必须在CreateFolders表中列出。

一旦你知道这意味着什么,这就很有信息量了。

2个回答

52

每个组件都有一个关键路径,最常见的是文件。您的组件没有文件或其他关键路径,因此WiX为其提供默认目录。然后Windows Installer会说具有目录关键路径的组件必须确保创建该目录,即使其他东西也会这样做。这是一个愚蠢的规则,但很容易解决。


1
我理解其中一部分 - 组件需要一个关键路径,默认情况下它会获取一个目录,并且<CreateFolder/>是必需的,以确保它正常工作。但是这个目录是哪个,位于哪里?这样做安全吗?这是否会在安装过程中在目标机器上创建空的(垃圾)文件夹?有没有更简洁的方法来完成这个任务? - Bevan
1
这取决于您告诉组件其父目录是什么。根据错误消息,它是INSTALLDIR。 - Bob Arnson
@Bevan:在一个空组件中缺少CreateFolder条目,该组件设置为安装到一个没有其他文件的空文件夹中,将触发一种奇特的情况,即Windows Installer在启动后删除该文件夹(因为空)然后Windows Installer尝试通过广告快捷方式在下一次启动时重新放置它(这会触发关键路径检查)。这种无聊的重复会无限循环。我刚刚验证了一下,测试是否已经在较新版本的Windows Installer中修复了此问题,但我仍然看到了这个问题。CreateFolder条目可以防止这种奇特的自我修复问题。 - Stein Åsmul
1
@Bevan:仅供参考,这个问题与常见自我修复问题摘要中的问题2相同:如何避免使用WiX / MSI包触发MSI自我修复? - Stein Åsmul

22

您可以在组件标记中使用参数KeyPath="yes"。前提是'INSTALLDIR'是该组件的正确路径。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接