【问题标题】:Wix installer: unzip an archive that the user selected during installationWix 安装程序:解压缩用户在安装过程中选择的存档
【发布时间】:2023-03-11 21:30:01
【问题描述】:

有一个安装程序允许用户从磁盘中选择一个 zip 文件,我们想将该文件解压缩到安装目标目录中。

这可以通过标准 wix 工具集/扩展实现吗?我们是否需要创建自定义操作?

目前,我们正在做这样的事情CreateObject("Shell.Application"),然后像这样使用它objShell.NameSpace(installDir).CopyHere(objShell.NameSpace(configPath).items), 20

但我觉得这不是一个好方法,而且 Windows UAC 也有问题。


编辑:动机是拥有一个 msi 安装程序和几个自定义 zip。当客户安装应用程序时,他会获得 msi 和其中一个 zip,并在安装时选择 zip(或在自动安装中作为参数发送)。

【问题讨论】:

  • 在安装过程中解压 zip 似乎不是一个好主意。
  • @BrianSutherland 你是对的,问题是我们有一个安装程序,将为每个客户安装额外的东西。附加内容在 zip 文件中。我同意这不是很好的方法,但现在就是这样。
  • @FrantišekŽiačik 您的评论让我觉得您正在尝试为(可能)每个客户部署自定义工件。我已经写了一个解决这种情况的答案。如果确实如此,您能否更新您的原始问题以阐明解压缩文件的意图(即,是否允许您(安装程序作者)自定义每个客户端的安装,或者是否允许客户端、安装程序消费者,通过选择要部署的任意 zip 文件来自定义他们的安装)。
  • 刚刚添加了一个答案,其中包含一些有关预处理器构造的信息 - 检查这是否是您真正需要以灵活的方式实施设置。
  • @pixelTitan 添加了有关意图的信息

标签: .net wix windows-installer


【解决方案1】:

我喜欢使用的一种模式是在我的 WiX 安装程序中创建一个扩展点,称为 Extension.wxs。该文件的默认(或标准)版本如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="INSTALLLOCATION">
            <!-- Setup all of the extension components here. -->
            <!-- For example...
            <Component Id="INSERT_COMPONENT_ID_HERE" Guid="{8451AFA1-5185-468D-B0A0-650494251D8F}">
                <File Id="INSERT_FILE_ID_HERE" KeyPath="yes" Source="SomeExtension.dll" />
            </Component> -->
        </DirectoryRef>             
    </Fragment>
    <Fragment>
        <ComponentGroup Id="ExtensionComponentGroup">
            <!-- Reference components that are extending the standard product here -->
            <!-- <ComponentRef Id="INSERT_COMPONENT_ID_HERE" /> -->            
        </ComponentGroup>
    </Fragment>
</Wix>

无论您想要自定义的Feature 是在哪里定义的,您都可以添加对此ExtensionComponentGroup 的引用,如下所示:

<Feature Id="MyMainFeature"
         Title="My Main Feature"
         Level="1"
         Description="An awesome feature, needed to run the application.">
  <ComponentGroupRef Id="MyMainComponentGroup" />
  <ComponentGroupRef Id="ExtensionComponentGroup" />
</Feature>

在我的例子中,我只是使用一组 Powershell 脚本来构建我的安装程序,因为它可以更轻松地动态确定向 WiX 工具集 CLI 提供哪些内容。因此,我对 candle.exe 的标准调用如下所示:

"C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe" -out .\obj .\src\Product.wxs .\src\Extension.wxs

但是,当我需要使用客户端特定文件自定义安装程序时,我只需更改命令行,使其指向自定义的 Extension.wxs 文件(类似于将其“注入”到构建管道中):

"C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe" -out .\obj .\src\Product.wxs .\SomeClientWithSpecialNeeds\Extension.wxs

使用 Powershell 时自定义这些命令行调用变得容易得多,但为了简单起见,我省略了 Powershell 脚本。

总之,我建议您将 zip 文件的内容表示为单独的 Component 元素,并将其注入到安装程序的构建管道中的单独 Extension.wxs 文件中。这些组件存储在由相应的Feature 引用的ComponentGroup 中。通过创建一个合适的默认值(空的,没有组件)Extension.wxs 文件,您仍然可以在没有任何自定义组件的情况下执行构建。使用此模式的另一个好处是,在卸载产品期间将卸载所有额外组件,并且您不必编写任何会增加安装程序维护开销的易碎自定义操作!

希望这对某人有所帮助。

【讨论】:

  • 非常好的文章,有点类似于预处理器的使用。我添加了一个关于如何使用预处理器变量的答案。不确定哪种方法最简单,但我认为在构建流程时使用预处理器更灵活。
  • 感谢@SteinÅsmul,我绝对认为预处理器方法在各种 WiX 工具集构建技术(即 Visual Studio 与 CLI)中更加灵活。在我的情况下,我采用“注入”方法,因为我一直喜欢标准安装代码库(或可执行代码库,就此而言)可以与自定义实现分离的概念。如果用户对标准代码库和自定义代码库之间的更强耦合感到满意,我绝对认为您的答案是要走的路。
【解决方案2】:

预处理器构造:如果您需要向不同的客户提供不同风格的设置,我喜欢使用 pre-processor constructs 来为每个客户端编译一个 MSI。 Here is a very lenghty description of this approach(可能检查底部的代码sn-ps)。

Pre-Processor Constructs In Use:我将内联上面的代码/标记,链接答案并进行一些调整以使其更清晰(我发现这个一种非常“编码器友好”的方法——这对于 C++ 开发人员来说尤其是非常熟悉的领域——使用预处理器结构是):

<?define ClientName = “Apple” ?>

<...>

<!-- You can put your vendor-specific components in an include file  -->
  <?if $(var.ClientName ) = "Apple" ?> 
    <?include "AppleFeatures.wxi" ?>
  <?endif ?>
  <?if $(var.ClientName ) = "Microsoft" ?>
    <?include "MicrosoftFeatures.wxi" ?>
  <?endif ?>

<...>

基本上预处理器构造允许您在编译和链接之前动态更改 WiX 源文件,因此您可以随意包含或排除某些部分。您可以通过设置一些参数来做到这一点 - 例如客户端名称 - 然后您可以使用它们来输出特定的 MSI 文件名:YourProduct_AppleEdition.msiYourProduct_SonyEdition.msi等等……

以下是本地化变量预处理器变量包含文件之间区别的简要说明:WiX (Windows Installer Xml), Create universal variables

【讨论】:

    猜你喜欢
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多