【问题标题】:Wix conditional component installation based on checking if fileSearch property is unset基于检查 fileSearch 属性是否未设置的 Wix 条件组件安装
【发布时间】:2018-02-14 20:55:45
【问题描述】:

根据我们产品安装的要求,我们需要在用户计算机的 C:\Windows\System32 中安装一些 dll。由于如果源的版本高于目标的版本,Windows Installer 会自动安装更高的版本,并且这样做会在用户不知情的情况下修改用户的系​​统,所以当 dll 已经存在于 C:\Windows\ 中时,我希望组件块根本不触发系统 32。这就是为什么我要进行 FileSearch 并将属性设置为一个值以防文件存在的原因。根据文档,它将是指定文件的路径。

    <Property Id="VCOMP_EXISTS_LOCAL">
      <DirectorySearch Id="vcomp_parent_dir" Path="$(var.SystemPlatformFolder)">
        <FileSearch Id="vcomp_file" Name="vcomp140.dll"/>
      </DirectorySearch>
    </Property>

稍后我将使用 VCOMP_EXISTS_LOCAL 属性,如以下块中所示有条件地安装组件。

    <ComponentGroup Id="AdditionalDependencies" Directory="$(var.SystemPlatformFolder)">
        <?if $(var.vcomp140_exists) = "true"?>
            <Component>
              <Condition>NOT VCOMP_EXISTS_LOCAL</Condition>
              <File Source="$(var.AdditionalDependenciesRoot)/OpenMP/vcomp140.dll"/>
            </Component>
        <?endif?>
    </ComponentGroup>

问题是,当我针对目标文件存在的情况进行测试时,我看到我的安装程序文件(更高版本)已替换目标文件,而根据上述逻辑,它不应该摸过它。此外,我没有看到详细日志中回显的属性值。我在日志中看到的就是这个

AppSearch:属性:VCOMP_EXISTS_LOCAL,签名:vcomp_file

而不是通常情况下的以下内容。

属性(S):VCOMP_EXISTS_LOCAL = C:\Windows\System32

外部条件预处理器指令用于检查另一个条件,其中 var.vcomp140_exists 在编译期间传递给candle.exe(使用 -d 开关)。所以这是一个构建/编译时间条件。我知道外部条件有效(传递的值为真)。 WI 似乎忽略了内部安装时间条件块。可以这样混吗?

如果可以,我想我的问题是不知道如何检查是否设置了属性值。我在 Wix 文档的某处发现,如果搜索失败,属性将保持未定义或保持其原始值。在这种情况下,我想它将是未定义的。问题是如果'NOT PROPERTYNAME'是你如何检查它?任何帮助都感激不尽。纠结这个问题好几天!

【问题讨论】:

    标签: visual-c++ wix windows-installer


    【解决方案1】:

    您用作条件的语法是preprocessor,它在构建时解析,而不是运行时解析。您需要使用适当的expression 制作conditional,并在文件搜索后进行评估。

    【讨论】:

    • 谢谢。有没有可以看的例子?
    • 我认为我的问题是在评估内部条件时属性没有获得值。我看到设置属性的唯一方法是使用 setProperty。当我使用以下。 NOT VCOMP_EXISTS_LOCAL 我看到文件没有被复制,即使它不存在于目标中。日志显示 setProperty 设置的 VCOMP_EXISTS_LOCAL 值。
    • 其实inner or install time 条件的语法是对的。问题是将整个目录作为 directorySearch 元素中的路径传递。当我使用多个 directorySearch 元素(每个元素一个文件夹)嵌套子文件夹时,我能够看到属性 VCOMP_EXISTS_LOCAL 正在被评估。它还证明了您可以通过检查构建时间(使用预处理器)来安装组件,并在单个组件块中同时安装时间条件。
    • 并且不需要使用 setProperty 设置属性的默认值(当目标文件夹中不存在文件时)。
    【解决方案2】:

    除了组件状况之外,没有必要这样做。分发 VC++ 可再发行组件的标准方法是运行 redist 包作为先决条件。当您说“我的安装程序文件(更高版本)已替换目标文件”时,您根本不应该这样做。您冒着破坏客户端系统的风险。

    我还注意到,像这样的共享 Dll 是使用 Windows Installer 组件 ID 共享的,因此每个使用类似 vcomp140.dll 的产品都会使用相同的组件 ID 安装它。同样,您只需使用您自己的组件 ID 安装该 Dll,就有可能破坏该 Dll 的共享。

    正确的做法是运行 redist 作为先决条件,它只会做正确的事。

    【讨论】:

    • 谢谢。我同意不使用系统文件夹。现在,为了简单起见,我们只是在 bin 文件夹中添加 dll。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多