【问题标题】:WIX: copy file to custom dir in another partitionWIX:将文件复制到另一个分区中的自定义目录
【发布时间】:2018-01-03 02:32:57
【问题描述】:

我需要将应用程序的文件安装到通常的位置,例如 C:\Program Files\MyApp
并且还需要将其中几个复制到另一个分区的自定义文件夹中
(假设D:\CustomFolder,允许对其进行硬编码)。

安装应该是静默的——没有 gui 或向导。此外,所有内容都应该在一个 *.msi 文件中。

我可以通过CustomActions 做到这一点,但更可取的是优雅的声明方式。

以前有人试过吗?
谢谢。

更新: 忘了说,应该在单独分区上的文件是允许在C:\Program Files\MyApp

【问题讨论】:

    标签: wix windows-installer


    【解决方案1】:

    解决了。方法是:

    1. 指定应放置文件的自定义文件夹:

      <Property Id="MY_CUSTOM_DESTINATION" Value="D:\MyCustomFolder" />

    2. <Copy ..> 指令放入应复制的<File ...>

    <DirectoryRef Id="MyAppFolderThatIsInProgramFiles">
         <Component Id="MyComponent" Guid="some_guid">
          <File Id="MyFileXml" Source="MyFile.xml" KeyPath="yes" >
              <CopyFile Id="Copy_MyFileXml" DestinationProperty="MY_CUSTOM_DESTINATION"/>
          </File>
         </Component>
    </DirectoryRef>
    

    附言作为副作用,&lt;File Id="MyFileXml" ... /&gt; 中指定的文件将被放入两个位置:C:\Program Files\MyAppD:\MyCustomFolder,但这对我的任务是正确的。

    【讨论】:

    • 这不是副作用 - 这是它的工作原理,它是设计使然。当您在 File 元素下嵌套 CopyFile 时,这会导致 DuplicateFile Windows Installer 表的记录。如果您将 CopyFile 直接嵌套在 Component 元素下,这意味着您不会安装该文件,而是将外部文件复制到指定位置。我建议你更好地理解底层的 Windows Installer 概念——这样你就会明白为什么 WiX 会这样工作:)
    • 移除结束标签DirectoryRef
    【解决方案2】:

    硬编码目录违反 Windows Installer 最佳实践。你永远不能假设总会有一个 D: 甚至是一个 C:。尽管如此,客户仍然要求(要求)我在 D:\FOO 中安装一些东西。

    那么,如何让客户满意并让安装在没有 D: 的 VM 上仍然“工作”?通过在安装时使用自定义操作重定向目录,该操作仅在 D: 是固定硬盘时重定向。

    此外,虽然 CopyFile 元素很有用,但它并不是真正需要的,因为您可以将文件编写到组件中两次,并且 smartcabg 将确保您的 MSI 不会通过让文件记录指向相同的条目而膨胀媒体\驾驶室存储。

    【讨论】:

    • 我只处理内部使用的产品,D:\MyCustomFolder(这是其他产品之间共享的知名位置)的存在是一种先决条件。我知道硬编码的目录通常很糟糕,但在我的情况下,这不是问题。
    • 对不起,你还没有卖给我。您的团队只是增加了技术债务并合理化了糟糕的设计。
    • 是的,我意识到这一点。一旦有必要(这当然有可能,但不太可能发生),我们将轻松偿还这笔债务。
    • 我希望硬编码的目录引用在构建 MSI 文件时根本不会编译。如果人们需要这样的非标准路径来安装 - 我实际上会使用除 MSI 之外的其他一些部署技术。或者,正如您所建议的,对于像这些不寻常的路径这样的时髦的东西,实际上可能需要一个自定义操作来提供一些优雅地降级或做一些聪明的事情——即使自定义操作几乎总是不受欢迎的。
    • 这是优雅降级的一部分。如果 CA 因任何原因失败,您只需忽略同步并且什么都没有发生……默认目录结构适用。对于我们技能水平的人,我不相信“几乎总是”。我们已经解决了 99.9% 的设置问题,而无需借助自定义操作。对于初学者来说,“几乎总是”可能适用。
    【解决方案3】:

    您可以在目录标签下简单地描述您的磁盘结构:

    <Property Id="DRIVE_1" Value="c:\" />
    <Property Id="DRIVE_2" Value="d:\" />
    <Property Id="DRIVE_3" Value="e:\" />
    
    <Directory Id="TARGETDIR" Name="SourceDir">
        <Directory Id="DRIVE_1" />
        <Directory Id="DRIVE_2" />
        <Directory Id="DRIVE_3" />
    </Directory>
    

    我不提倡硬编码,但你明白了。

    【讨论】:

    • 这不起作用 - D:\ 是无效名称,因为不允许使用 \ :
    • 您是否对这些值进行了硬编码?如果这是您想要的,请将它们放在属性中。
    • 我已将值作为属性放入 *.wxs 文件 &lt;Property Id="MY_CUSTOM_DESTINATION" Value="D:\MyCustomFolder" /&gt;。如果我没记错的话,可以通过从命令行将其作为安装程序参数传递来覆盖MY_CUSTOM_DESTINATION 值。
    • 是的,这是正确的,只需在命令行中传递它们:msiexec /i misname.msi MY_CUSTOM_DESTINATION="d:\" 这将是更好的方法,您不会收到 ICE 验证错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 2017-11-18
    • 2013-06-01
    • 2020-06-22
    • 2014-08-12
    • 2013-10-24
    相关资源
    最近更新 更多