如何为 WIX 中的目录分配路径值?

2024-05-23

在我的 WIX 项目中,我有一个类似这样的目录结构:

<Directory Id="TARGETDIR" Name="SourceDir">
  <Directory Id="INSTALLLOCATION" Name="FolderName">
   ...
  </Directory>
  <Directory Id="MYDIRECTORY" Name="SomeDifferentDirectory">
   ...
  </Directory>
</Directory>

Here INSTALLLOCATION代表我的程序的安装文件夹,但我想在安装目录之外另外创建另一个目录,例如,D:\MyFolder1\MyFolder2,从上面的示例中我如何将该值分配给MYDIRECTORY以便安装完成后会创建它?


我没有时间测试下面列出的选项,但它们应该是可行的、技术上的可能性。希望其中一个选项能够令人满意。

但是,首先: 我不喜欢这种设置二级顶级目录的方法 - 真的需要吗?你能解释一下这个场景吗?也许有更可靠的方法?

参见“备择方案?”部分,我认为这是比“摆弄”目录属性更好的方法。如果我是你,我会首先阅读这个“替代方案?”部分 - 也许它可以为您节省很多麻烦?

但第一部分涉及各种技术选项来完成您的要求:


设置目录属性

设置目录属性的方法有很多种,我一时想不起来。正如我所说,我还没有时间测试这些选项 - 发布未经测试的建议总是很疯狂,但你似乎可以为自己提供一些指导:

  1. AppSearch http://wixtoolset.org/documentation/manual/v3/xsd/wix/appsearch.html - you can search the system for a specific file or registry entry and set the directory property to the path found (if any).
    • 通常,您需要的路径可以通过这种方式找到 - 并且也可靠,因为它是一个内置功能(因此比您自己的任何自定义构造都经过更好的测试)。
    • 如果需要,您还可以添加自定义操作来验证找到的目录是否有效。此类“验证数据”自定义操作可以非常安全,因为它们不会更改系统 - 但如果您不小心并允许它们返回错误代码或中止设置,它们仍然可能导致意外的运行时故障。
  2. A Set Property Custom Action https://msdn.microsoft.com/en-us/library/windows/desktop/aa368237(v=vs.85).aspx (Custom Action Type 51). Just set the path to something like [ROOTDRIVE]MyFolder.
    • 如果有人这样做,我会因为质量原因而使包裹失败(技术上是可能的,但是根驱动器 https://msdn.microsoft.com/en-us/library/windows/desktop/aa371372(v=vs.85).aspx可能会根据每个驱动器上的可用磁盘空间切换到指向不同的路径 - 一点也不好)。
    • 了解可能性,寻找它,如果发现它就修复它。不要使用它。黑暗的一面很诱人。
    • 讽刺的是,如果我诚实的话,设置一些东西[WindowsVolume]MyFolder- 可能确实有效,但我个人不喜欢它。我首先不希望将任何内容安装到系统驱动器上的顶级文件夹中。
    • 我相信 WiX 有SetDirectory Element为了这个“设置属性”的目的。我认为它可以为您完成所有自定义操作。一些自动魔法。但是我不确定此功能是否允许从命令行覆盖公共属性?
    • If you set something to D:\MyFolder you have to be aware that this path could at some point be missing unexpectedly (drive removed from system, new drive added (?), new DVD drive added (?), drive letter manually changed, etc...).
      • 这超出了正常的“设置属性”操作 - 它本质上是“硬编码”(请参阅​​下面的问题 5)。硬编码是永远不可接受的- 适用于任何通用分发包。
      • 我更愿意瞄准PersonalFolder(我的文档),然后将其重定向到 Windows 本身的 D:\。我相信Windows随后会分配一个新值PersonalFolder如果在启动时找不到它。然后,Windows Installer 仍然能够枚举目标文件夹,而不仅仅是卡住或崩溃。
  3. 将目录设置为特征目录在安装程序 GUI 的自定义对话框中公开。

    • Mad to suggest since I have never used it, but it is an viable option I think - but requires significant testing in all installation modes (install, repair, self-repair, uninstall, modify, patching, et...) to make sure it works as desired.
      • 快速更新:我做了一个冒烟测试,它有效,但我想说这并不是一件小事。请参阅下面下一节中的模拟 GUI 示例和一些 WiX 片段.
    • 这涉及到为设置到此功能目录的组件添加单独的功能。然后你设置ConfigurableDirectory的属性FeatureElement在你的 WiX 源中等于保存目录路径的 PUBLICPROPERTY。
    • 如果您使用对话框集,您现在应该能够从 WiX GUI 设置此目录Mondo (<UIRef Id="WixUI_Mondo" />) - 来自 ”Custom” 对话框。这里有一个使用 Visual Studio 更新 WiX 源文件以使用 Mondo 的分步示例:WiX 安装程序 msi 未安装使用 Visual Studio 2017 创建的 Winform 应用程序 https://stackoverflow.com/questions/47970743/wix-installer-msi-not-installing-the-winform-app-created-with-visual-studio-2017/47972615#47972615.
    • 您所做的 GUI 选择(目录)将分配给您指定的属性ConfigurableDirectory对于该功能。
    • 不知何故,您必须将目录属性设置为对静默安装有意义的内容(当跳过 GUI 时),或者如果在命令行上没有为该属性定义任何内容,您可能会中止安装。
    • 我会在其中检查有效目录并防止普遍的疯狂行为,例如安装到系统文件夹、直接安装到 C:\、安装到其他产品的现有文件夹等...... - ”" - 格雷迪·布奇 https://en.wikipedia.org/wiki/Grady_Booch- 赖以生存的话语,多么酷的名字 - 和头发 - :-)。
  4. A 常规、即时模式自定义操作(不是设置属性自定义操作)它通过调用来设置属性会话.属性= 代码中某处的“SomeValue”。每种类型的自定义操作类型的“属性集”略有不同(自定义操作类型:VBScript、C++、DTF / C# 等...请参阅高级安装程序的文档 https://www.advancedinstaller.com/user-guide/set-windows-installer-property-custom-action.html了解如何做到这一点)。

    • 我总是告诉人们避免自定义操作,对于读写自定义操作来说绝对如此:为什么在 WiX / MSI 设置中限制自定义操作的使用是个好主意? https://stackoverflow.com/questions/46179778/why-is-it-a-good-idea-to-limit-the-use-of-custom-actions-in-my-wix-msi-setups/46179779#46179779.
    • 但是,我确实使用只读自定义操作集来抑制错误,并且不返回在需要时回滚设置的错误。这使您能够在您认为合适的情况下检查系统,以确定对相关属性设置什么。
    • 至关重要的是这样的立即模式只读自定义操作不需要回滚功能由于它们没有对系统进行任何更改,因此它们也不会提升运行权限,并且大多数“存在于 GUI 序列中”,用于从用户获取数据和设置 - 或检查目标系统的各种条件和状态 -只是检查东西(如果跳过 GUI,静默安装序列中通常也需要它们)。
    • 请记住,在静默安装模式下会跳过 GUI 序列,因此您的自定义操作必须存在于两个序列中。不过,您可以将其设置为仅运行一次。
  5. 有些人甚至硬代码路径在属性表中,或使用设置属性自定义操作来分配C:\在运行时的属性 - 根本不可接受。这会打破——这只是时间问题。对于初学者来说,在没有 C:\ 驱动器的计算机上,它根本不会安装。

    • 不确定在属性表中设置的此类属性是否会在期间被覆盖directory resolution and costing- 我从来没有费心去尝试 - 这不是一个解决方案,我只是想声明这一点以防止其使用。

    • 设置属性自定义操作分配C:\或类似的财产似乎会起作用,但会以意想不到的方式爆炸。有保证。

    • 再次强调:如果可以的话,请不要部署到单独的顶级文件夹。

  6. 我听说有些人 - 在公司、标准化环境中 - 使用环境变量定义此类安装文件夹。我从未将它用于生产,从未尝试过将其用于测试,也不喜欢将其作为一种选择。

请记住,公共属性可以在命令提示符下设置 - 因此可能会覆盖您添加的任何逻辑以自行设置。也许添加一个自定义操作来检查来自命令行的值,如果错误则接受它或中止设置。


具有可配置功能目录的 WiX 安装程序

以下是具有可配置功能目录的 WiX 安装程序的 GUI 屏幕截图:

上面看到的浏览按钮仅适用于具有ConfigurableDirectory属性指定指向自定义目录属性(忽略C:\上面屏幕截图中的条目 - 只是一个小问题):

<!-- A standard feature -->
<Feature Id="ProductFeature" Title="MinimalShortcutTester" Level="1">
   <ComponentGroupRef Id="ProductComponents" />
</Feature>

<!-- A configurable directory feature -->
<Feature Id="FeatureDirectory" Title="FeatureDirectory" ConfigurableDirectory="MYCUSTOMDIR">
        <!-- your stuff here -->
</Feature>

在 WiX 源代码的其他地方,实际的可配置目录:

<Directory Id="MYCUSTOMDIR">
     <!-- Mock-up GUID that MUST be changed, custom target directories do not function with auto-GUIDs -->
     <Component Id="MyFile.exe" Guid="{00000000-0000-0000-0000-000000000000}" Feature="FeatureDirectory">
         <File Source="C:\SourceControl\MyFile.exe" />
     </Component>    
</Directory>

我会使用额外的自定义操作来默认它MYCUSTOMDIR目录,或者检查用户所做选择的有效性。这并不完全是直截了当的,但必须根据具体情况进行处理。

再想一想,我可能会使用set property custom action将 MYCUSTOMDIR 目录默认为以下子文件夹PersonalFolder,然后允许用户在安装时覆盖它。现在您必须读回用户对修改和修复(以及其他安装模式)的选择,否则您将默认为PersonalFolder以及您在其他安装模式中指定的任何子文件夹。您可以将用户文件夹选择保留在注册表中,并使用AppSearch(我认为这是大多数专业人士的偏好)或者通过自定义操作完成这一切。在所有安装模式下使其正常工作可能具有挑战性。好好测试吧。

技术挑战:如果您保留原始文件夹选择MYCUSTOMDIR在注册表中并将其读回AppSearch,您必须确保设置属性自定义操作的条件(用于将默认值设置为MYCUSTOMDIR如果没有设置值),这样如果属性已经从注册表中检索到值,则它不会运行。这不是火箭科学,但要正确执行可能会很繁琐 - 并且对所有安装模式下的测试都吹毛求疵。如果您依赖标准构造而不是自定义操作,一旦您了解所涉及的“移动部件”,您通常会受益 - 首先,您在第一次安装时默认,因为尚未设置值(除非通过命令行设置值),然后您允许它在 GUI 中(或通过命令行)被覆盖,然后在安装过程中保留在注册表中,在下次启动(修复、修改、自我修复、升级、修补)时,您读回保留的值并且不让通过条件等设置默认值...

为了安全起见,添加一个链接:Wix:禁用内置对话框中的控制 https://stackoverflow.com/questions/48377866/wix-disable-control-in-built-in-dialog/48403443#48403443.


备择方案?

如上所述,这些二级顶级目录层次结构通常可以通过更好地理解替代方案来避免。

检查替代方案的一些问题:

  • 哪些文件将进入该辅助顶级文件夹?数据文件?数据库?
  • Often such folders are for data files, and sometimes the folder used is unique for each user (i.e. not a shared folder). For example "My Documents".
    • 在这些情况下,我喜欢让应用程序在启动时创建文件夹(将具有对此类文件夹的写访问权限),然后从安装在 %ProgramFiles 下某处的只读模板副本将每个用户所需的任何文件复制到该文件夹​​中%。
    • MSI 不太适合部署用户配置文件。我在这里写了一些问题的总结:从管理员配置文件中在当前用户配置文件上创建文件夹和文件 https://stackoverflow.com/questions/48189243/create-folder-and-file-on-current-user-profile-from-admin-profile/48196886#48196886。通常不清楚如何引用计数多次部署的文件(每个用户一次)。
    • 我多次重复这个建议,但有时处理用户配置文件部署确实是一场噩梦。非常常见的问题:(1)意外的数据覆盖/重置,(2)无法将用户配置文件复制到位,(3)意外卸载修改的文件(读取:用户数据),(4)无法可靠地覆盖现有文件 - 相同的问题倾向于重复。
  • 当然,也可能出于其他原因需要这样的顶级文件夹,但我敢打赌,它将填充用户数据或用户可修改的文件。这准确吗?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何为 WIX 中的目录分配路径值? 的相关文章

  • Microsoft Visual Studio 安装程序项目 - 如何向使用 Process.Start() 执行但没有修复选项的 MSI 提供重新启动提示

    问题如下 我在 MSI 卸载之前调用了自定义卸载程序 正确关闭我的应用程序后 它会调用msiexec使用 Windows Installer 卸载 MSI 这是通过执行 msiexec x PRODUCT CODE promptrestar
  • 如何在 WIX 中引用用户的主目录

    我正在为 SDK 创建一个安装程序 其中包括由最终用户编译的源代码 我希望我的 Wix 安装程序默认将其放入用户的主目录中 但我找不到要使用的正确属性名称 您还可以参考HOMEPATH环境变量与 HOMEPATH 有关用于属性的语法的更多详
  • wix 3 安装程序:未解析的绑定时变量!(bind.fileVersion.Name.exe)

    我正在尝试使用 Wix3 中的绑定 bind fileVersion 即 3 11 1 由于某些原因 我收到以下错误消息 未解析的绑定时变量 bind fileVersion TestWix3 exe 我的目标是填写 产品 ID 行 特别是
  • 生成Mst响应工具

    我正在尝试使用 C 创建一个工具来获取通过单击 msi Windows 安装程序 的对话框生成的属性 我可以通过在 msi 关闭之前读取 property 表来获取最终的 msi 属性 但这包含相当多的不需要的属性 例如目录等 我希望能够做
  • 维克斯。相同版本不同产品代码如何进行重大升级?

    基本上我需要改变这种行为 安装具有相同版本和升级代码的产品 但 不同的产品代码 是允许的 并被 MSI 视为两种产品 我需要将其作为重大升级进行威胁 因此 在 v 1 0 1 旧版本 不同的 ProductCode 上安装 v 1 0 1
  • WiX:数字签名 BootStrapper 项目

    我有一个项目 我为其构建了 WiX msi 文件 我还有一个 WiX 引导程序 exe 文件 用于检查 C 2005 是否存在 如果未找到则安装它 然后安装 msi 软件包 我的项目包括作为 msm 文件的 Crystal Reports
  • 要求 WIX Bootstrapper 在 .NET Framework 安装后重新启动并跳过应用程序启动

    感谢安德烈在这里的回答 使用 WIX 安装程序安装 NET Framework 4 7 2 如果需要 https stackoverflow com questions 53640255 install net framework 4 7
  • 压缩未压缩的 MSI 文件

    我们有一个安装项目 它生成一个未压缩的 MSI 文件 并且根本没有 Setup exe 稍后由 NSIS 压缩 在特殊的构建设置中 我想在 NSIS 打包之前复制该 MSI 更改副本并保留它 我还想在 msbuild 创建它之后对其进行压缩
  • 在 Linux 中使用 Python 读取 EXE、MSI 和 ZIP 文件元数据

    我正在编写一个 Python 脚本 将大量 Windows 安装程序索引到数据库中 我想知道如何使用在 Linux 上运行的 Python 从 EXE MSI 和 ZIP 文件中读取元数据信息 公司 产品名称 版本等 Software 我在
  • Wix 4 收获目录的解释?

    我正在尝试学习 Wix 4 0 来为我正在开发的应用程序创建安装程序 构建我的应用程序后 我在一个文件夹中有一堆文件 我想将它们安装到程序文件中 我已经读到收获功能允许我简化此过程并为整个目录创建组件映射 但我不确定这是什么example
  • 如何禁用恢复 Visual Studio 安装程序项目丢失的文件?

    我创建了一个使用来自暴雪 API 服务的图像的程序 我为该程序创建了一个安装程序 并将图像放置在 用户的应用程序数据文件夹 中 安装非常好 图像被解压到文件夹 AppData Roaming MyApp 中 如果需要删除图像 程序将从暴雪服
  • 让 WiX Bootstrapper 用于 .NET 4.0 的引导

    我一直在寻找让我的引导程序能够安装 NET 4 0 和我自己的应用程序 我查看了几个博客和教程 但无法让它发挥作用 我在 Stack Overflow 问题中读到在 WiX 中启动 调用引导程序 https stackoverflow co
  • WIX 检测待重启

    我正在使用带有 WiX 的自定义 BA 我想检测是否存在挂起的重新启动 以在用户尝试安装之前警告他们 结果却失败了 如何在 Burn WiX 中引用重新启动挂起属性 https stackoverflow com questions 108
  • 无法使用wix工具集创建postgresql数据库

    我正在尝试使用 Wix ToolSet 在 PostgreSQL 中创建数据库 但总是收到错误 错误 2147467259 无法创建 SQL 数据库 pontow 错误详细信息 未知错误 当我尝试创建数据库或错误 无法连接到 SQL 数据库
  • 如何在 MSBuild 中创建新属性并在 WIX 中引用它

    我们需要创建一个属性来指示我们的软件版本 然后我们想在我们的 WIX 项目中使用它 即在 wxs 文件中引用它 我们不想在 wxs 文件中定义它 因为我们希望 MSBuild 也根据此版本号重命名输出文件 PropertyGroup 中的常
  • WIX Heat.exe 命令参数 -var 不接受空格?

    我有这个使用所有不变路径的 WIX 命令 并且它不需要系统环境 与此示例不同 http weblogs sqlteam com mladenp archive 2010 02 23 WiX 3 Tutorial Generate filed
  • 为什么我的应用程序会触发另一个应用程序的安装程序?

    当使用旧版 VB6 应用程序并在该应用程序中打开某些特定表单时 会弹出属于 Microsoft Navision 安装在同一台计算机上 的 Windows Installer 如附图所示 每次都会发生这种情况 但仅限于这台机器 VB6应用程
  • 将引导程序与 MSI ui 一起使用

    我有可以安装的 MSI 文件 它包含一个定制的 UI 还收集用户的数据 作为安装的一部分 如果缺少的话我想安装以下内容 Net框架4 0 Microsoft Visual C 2010 可再发行组件包 x64 据我所知 引导程序也应该包含
  • WiX Heat:预构建事件在构建服务器上过早触发

    我正在为我的 Visual Studio 解决方案收集一个目录 到目前为止 它在我的本地系统上运行可能是因为项目构建顺序得到了尊重 当我在构建服务器上运行安装程序时 它会找到正确的目录 但在构建安装文件时尚未创建该目录 它抛出一个HEAT5
  • 在 Visual Studio 的 InstallShield 中创建 setup.exe

    Please tell me whether it is possible to create a file named setup exe I want to have the end user to a single file inst

随机推荐

  • 如何单击并验证弹出窗口(警报)是否存在

    我正在使用硒 当尝试单击按钮时 它会创建弹出窗口 警报 并且不返回页面对象 因此 我不能单独使用 click 因为此方法需要一个页面对象 并最终因超时而失败 我可以使用 chooseOkOnNextConfirmation 但这将单击弹出窗
  • TFS - 删除本地文件后最新字段仍显示“是”

    在 TFS 源代码管理资源管理器中 即使我已删除所有本地文件 我的项目在最新字段中仍标记为 是 有没有办法重新评估该列 使其再次显示 未下载 如果您想从本地文件系统 例如使用 Windows 资源管理器 删除文件并将源代码管理资源管理器中的
  • OS X Cocoa 自动布局隐藏元素

    我正在尝试使用新的自动布局 http developer apple com library mac documentation UserExperience Conceptual AutolayoutPG Articles Introdu
  • 为什么使用 1<<4 而不是 16?

    OpenJDK 代码为java util HashMap包括以下行 static final int DEFAULT INITIAL CAPACITY 1 lt lt 4 aka 16 Why is 1 lt lt 4在这里使用 而不是16
  • JQuery 颜色盒

    如何在没有事件绑定的情况下在页面加载时显示 Colorbox 更简单地说 我希望 Colorbox 在页面加载时立即加载 这是我目前正在使用的 Colorboxhttp colorpowered com colorbox http colo
  • 如何在 Python 2.7 中编写 unicode csv

    我想将数据写入文件 其中 CSV 中的行应如下所示 直接来自 Python 控制台 row xef xbb xbft 11651497 http kozbeszerzes ceu hu entity t 11651497 xml Szabo
  • 向Kademlia添加新节点,构建Kademlia路由表

    我无法完全理解 Kademlia DHT 的加入过程 我在网上看过一些教程和演示文稿 但它们似乎都以相同的方式说事 并且所有伪代码等在大多数情况下都是相同的 实际复制 粘贴 有人可以对此进行高水平的演练吗 我假设您已经阅读过木兰纸 http
  • 将自动递增值添加到只有一列的表中

    我需要创建一个基本上仅保留索引列表的表 因此 我创建了一个只有一个名为 id 的自动递增列的表 但是 我似乎无法隐式地将自动递增值添加到该表中 我知道通常当您在表中有这样一列 不仅仅是此列 时 您可以执行以下操作 插入表 col1 col2
  • PreRequestHandlerExecute 中的会话为空

    在我的 ASP NET 4 0 应用程序中 我在 global asax cs 中有一个 PreRequestHandlerExecute 的事件处理程序 我想访问会话中的数据 大多数时候 会话是被定义的 但有时它是空的 有人可以解释一下什
  • 为什么 Date.parse 给出不正确的结果?

    案例一 new Date Date parse Jul 8 2005 Output 2005 年 7 月 8 日星期五 00 00 00 GMT 0700 太平洋标准时间 案例二 new Date Date parse 2005 07 08
  • 如何查看 Realm ObjectId 是否等于 String (JavaScript)

    我正在使用 MongoDB 的 Realm 并尝试查看 ObjectId 是否等于具有相同字符的字符串 我尝试将 ObjectId 转换为字符串 反之亦然 但无论我尝试什么 它都不会将它们视为相等 即使这些值完全相同并且当我记录它们时它们看
  • 如何从 Tkinter 文本框中获取索引

    我希望能够从 Tkinter 文本框中突出显示的文本中获取索引 如 1 1 有什么想法吗 所选文本具有标签 sel 所选文本的开始和结束范围定义为 sel first and sel last 如果你想获取文本 可以直接使用它们 如下所示
  • Zurb Foundation 5 揭示模态不起作用

    我正在尝试使用 zurb Foundation 5 Reveal 模式 但当我单击按钮时它不起作用并且无法打开 我正在使用这个 html 代码
  • 在SQLAlchemy中获取相关模型

    我有各种模型链接在SQL炼金术 http en wikipedia org wiki SQLAlchemy 有很多 属于 等等 有没有办法找到给定实例的相关模型 就像是 usersModelInstance getRelatedTables
  • 在 SQL 中如何获得整数的最大值?

    我试图从 MySQL 数据库中找出整数 有符号或无符号 的最大值 有没有办法从数据库本身提取这些信息 是否有我可以使用的内置常量或函数 标准 SQL 或 MySQL 特定的 At http dev mysql com doc refman
  • 使用 linq 获取分组的逗号分隔值

    我想要第三列 项目 其中包含分组的值 var dic new Dictionary
  • 禁用 Angular 2 中的按钮

    我想如果输入 合同类型 为空 则 保存 按钮不可点击 保存按钮 div class col md 4 div
  • 没有生成缩略图

    我在我的项目中使用 Sonata Media Bundle 和 Symfony2 3 当我覆盖 YouTube 提供商时奏鸣曲 media provider youtube 一切工作正常 没有错误或任何其他内容 但在 Web uploads
  • Winforms——多选下拉列表

    我正在寻找一个允许我选择多个项目的下拉列表控件 类似于 CheckedListbox 但采用下拉列表形式 我不希望它占据屏幕的很大一部分 此时我非常确信 NET 中不存在这样的内置控件 请注意 这是 Winforms 而不是 ASP NET
  • 如何为 WIX 中的目录分配路径值?

    在我的 WIX 项目中 我有一个类似这样的目录结构