【问题标题】:Windows installer forbid certain install locationsWindows 安装程序禁止某些安装位置
【发布时间】:2018-05-25 03:17:03
【问题描述】:

拥有一个由用户手动运行的 msi 文件。在大多数情况下,他们需要能够选择安装目录,但是我们需要禁止某些安装位置。例如。将其安装到根目录C:\ 会导致各种问题,因此我们需要覆盖该决定(即用C:\Program Files (x86)\xxx 覆盖C:\)或弹出错误。有什么办法可以强制执行吗?

有问题的 msi 已经有自定义操作,但似乎没有办法从那里编辑安装位置。

或者,在这种情况下,msi 被封装在一个 WiX 包中,所以如果我们可以从那里禁止某些目录,那也很好。不过也找不到方法(只知道如何使用<Variable Name="InstallFolder" ...> 编辑默认值)

只有我能想到的其他解决方案会相当可怕:制作一个单独的应用程序,选择一个目录,然后使用可接受的目录运行安装程序。

这可以通过 msi 或 WiX Bundle 完成吗?

我正在使用“Visual Studio 2013 安装程序项目”扩展来构建 msi。

【问题讨论】:

    标签: c# wix windows-installer custom-action


    【解决方案1】:

    相反的观点:

    一般来说这是个坏主意。在大多数情况下,正确的答案是将应用程序代码安装到适当的 Program Files 文件夹(64 位或 x86),并将数据文件安装到数据位置等,用户应该别无选择。我不清楚当(例如)Windows 认证规则说您的代码必须转到 Program Files 位置时,选择是否是一个好主意,所以只要做对就行。用户只关心已安装的应用程序是否正常工作,如果安装到某些位置时失败,那么答案是 1) 修复应用程序以使其正常工作或 2) 使用 Program Files 并让用户别无选择。

    此外,如果您使用的是 Visual Studio 安装程序项目,则无法编写自定义操作来执行此操作,因为它们都运行得太晚而无法更改安装位置。你似乎已经发现了这一点。但是您可以隐藏浏览文件夹对话框并安装到默认的正确位置。

    另一个问题是不清楚如何定义“允许”位置。如果不是 C:\,那么它可以是 D:\SomeOtherLocation 吗?它可以是附加的USB驱动器吗?可以是 \\Servername\share 等网络共享吗?映射到网络共享的驱动器?可能有任意数量的选定位置会在安装或应用程序运行时失败,我认为没有一个有用的允许列表。最重要的是,假设您有 32 位安装,并且用户选择了 64 位系统上的本机 Program Files 文件夹,那么它甚至不会去那里 - 它将被重定向到 Program Files(x86)地点。最后,不清楚您在静默安装模式下所做的事情,假设用户在命令行上指定了一个位置,它未通过您的测试,然后静默安装失败(因为静默意味着静默,并且安装可能是无人值守的)。

    换句话说,只需安装到 Program Files 并完成它。

    【讨论】:

    • 好点。有太多没有意义的事情是可能的 - 对 OP 没有冒犯 - 他有工作要做。我从不喜欢重定向安装文件夹,但是当磁盘空间不足时,人们需要它。我们是否可以强制安装%ProgramFiles%(例外:GAC、WinSxS、系统等)和操作系统功能来处理空间不足的问题?自动系统驱动器迁移到新磁盘保留操作系统安装作为操作系统功能?似乎比允许存储在多个物理磁盘上更可靠,这些物理磁盘可能会在您取出物理磁盘的那一刻分崩离析或以某种方式发生故障?
    • 我同意不需要询问用户。几乎所有人都不需要改变它,有些人甚至不需要决定就被困在这个问题上。如果磁盘空间稀疏,他们可以创建一个连接点来修补他们需要的空间。如果他们真的需要覆盖安装文件夹,他们可以在命令行上设置它,因为它是一个公共属性。
    • 不幸的是,您提出了优点,这是能够选择位置的要求。不过你说的很对,很难预测用户可能会对安装程序做了什么愚蠢的事情。
    • 您的应用程序 - 在启动时 - 可以对其安装状态进行一些防御性检查吗?只是为了检查它是否可以在不会倒下的运行时环境中找到立足点。有一些有意义的错误信息?应用程序中的代码更易于调试和维护,并且不存在与模拟、排序和条件相关的问题 - 这往往会破坏自定义操作(即使设置 GUI 自定义操作比延迟模式自定义操作或静默自定义更容易)一般行动)。
    【解决方案2】:

    自定义操作:这会很短。稍后会回来查看。我不能说我最近一直在为实现这一点而烦恼,但是自定义操作当然可以检查安装位置并中止设置或停止它 - 如果发现所选路径不令人满意。还应该注意的是,由于目录表的实现方式,MSI 积极拒绝直接安装到 C:\ 的根目录以及类似的东西。

    GUI:我想一种方法是在用户单击设置的目标路径自定义对话框中的 Next 按钮时运行自定义操作,然后执行“任何你想要的”在检查路径方面,然后报告任何错误。这涉及到连接到路径自定义对话框上的OKNext 按钮的DoAction event

    静默模式:您还可以连接相同的自定义操作以在静默模式下运行(或另一个调用相同路径检查功能的自定义操作) - 以解决事实上,也可以为静默安装指定不需要的路径。在这种情况下,自定义操作应该在写入日志文件后中止设置,而不是向用户报告路径问题——这显然是你从上面提到的对话框事件中要做的事情。

    Github:我没有 WiX 代码供您在这台计算机上实现此功能。我会点击github.com 并搜索使用 WiX 的其他项目 - 你可能会很快找到一些东西 - 不花钱,WiX 是免费的。

    【讨论】:

    • 当我运行 msi 时,它不会阻止我在 C:\ 中安装。可能我正在使用不同的方式来构建 msi?我将把它添加到问题中。
    • 我喜欢记录人们不应该做的事情,而不是试图保护软件包免受用户可以想出的事情的影响。 Grady Booch 解释的原因:“用户在以意想不到的方式锻炼系统时具有惊人的创造力”。通常,您的保护功能中会出现错误 - 为您工作和悲伤,为您的用户带来烦恼。一份包含部署信息的非常简短且有用的单页 PDF 怎么样?以及该做什么的简短清单。 Maybe see the PDF-section here.
    • 你的包裹可能很大吗?它可以模块化,以便您可以从标准安装中省略某些部分吗?您可以使用MSI features 来允许这样做。您将获得“用户可选择的部分” 功能来安装或不安装。例如,您可以将“Developer SDK”排除在默认产品安装之外。或者您可以省略所有“帮助文件” - 而是依靠在线帮助等...我们知道部署是一件麻烦事,好的部署不能挽救坏产品,但糟糕的部署可以沉没一个好产品。
    【解决方案3】:

    基于用户能够手动安装它(因此使用 UI 序列),它可能更容易:

    1. 在 InstallUISequence 中,将 LaunchCondition 操作排序到 ExecuteAction 操作之前。

    2. 然后在 LaunchCondition 表中,添加如下条件:

      状况: 目标目录~

      说明: 您必须安装到 Program Files 文件夹

    我们在条件中所说的是:

    如果 TARGETDIR 以“C:\Program Files\”开头(因此用户可以安装此文件夹下的任何位置)继续安装。否则抛出错误。

    而不是阻止某些位置,我可能只是强制执行 Program Files 文件夹作为最佳实践。

    【讨论】:

      猜你喜欢
      • 2018-11-02
      • 2013-08-10
      • 2018-09-15
      • 1970-01-01
      • 2014-07-31
      • 2016-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多