使用开源软件5分钟搞定Windows应用安装包(msi安装包)

1,118 阅读7分钟

Windows Installer是微软提出的Windows平台上管理和配置软件服务的标准,也就是应用的安装方式。符合Windows Installer标准的安装包通常是以.msi格式的文件出现。因为Windows Installer安装包可以很好的与微软的企业管理系统配合,做到企业内对应用程序有管控的分发与升级,很多企业应用要求以Windows Installer安装包的形式提供。

Windows Installer是比较复杂的,为此微软也发布了一系列免费工具,如:WiX toolset,来减轻安装包的开发难度。WiX toolset功能是很强大的,但配置也很复杂,学习曲线相对陡峭。而且帮助文档说实话比较散,一些地方语焉不详。更麻烦的是,一些比较严重的bug,官方在v3.x版本中已经不再修复,需要等v4.x版本。但貌似v4.x版本的发布遥遥无期了。

现代Windows平台上的应用,已经越来越倾向于简单安装。这应该是得益于磁盘空间这种资源已不再紧俏,就像现在没人会在意典型安装、完全安装与自定义安装的区别一样。一个安装包能完成文件拷贝、注册表写入、创建快捷方式这些安装任务,就能满足大部分场景。这种情况下,我们需要更简单易用的工具。

WiX Cover是一款可以方便创建Windows Installer安装包的开源工具。其底层仍然使用的是WiX toolset技术,但屏蔽了大部分配置细节,并修复了一些已知问题。WiX Cover提供以下功能:

  • YAML格式的配置文件
  • 自动扫描源文件目录及子目录中文件,并打包到安装包中
  • 自动扫描注册表导出文件,并将相关注册表信息加入到安装包中
  • 环境变量添加删除支持
  • 最终用户许可协议确认
  • 安装到本机或当前用户
  • 安装结束后自动调起应用
  • 安装过程中自动终止旧版本应用进程
  • 多语言支持

因为WiX Cover的安装包就是用自身的技术来创建的,我们就用WiX Cover安装包的配置文件来介绍一下该工具的使用。
WiX Cover最新安装包可以从这儿下载:github.com/xinnj/WiXCo…
安装包的配置文件:github.com/xinnj/WiXCo…

我们先介绍一下配置文件的内容。

公共部分

Product:
  # Will be part of installation path, English only is preferred.
  Name: 'WiXCover'

  # Will be used to control upgrade process, SemVer is recommended.
  Version: '1.0.0'

# A GUID code. Should be kept unchanged for various versions of same product, but different with other products.
# Can use the command below to generate.
# powershell.exe -nologo -noprofile -command "[guid]::NewGuid().ToString().ToUpper()"
UpgradeCode: '84BE861F-CCF3-4582-80C3-C1BB5ABEA852'

# Will be part of installation path, English only is preferred.
Manufacturer: 'iCD'

配置文件的公共部分包括了:

  • 产品名称:这个名称会出现在安装包描述中,及作为缺省安装目录的一部分。因为有的软件对中文目录有兼容性问题,建议这儿的产品名称采用全英文。
  • 产品版本:会用于控制安装包的升级逻辑,建议使用SemVer规则。
  • 升级代码:这个用于在Windows Installer系统内区分不同产品。系统在安装应用时,如果发现系统内有同一升级代码的产品已经安装,会先把已安装产品卸载后再进行安装。所以一个安装包的升级代码确定后,在后续版本中就不能改变了。代码的生成方法可参见注释。
  • 生产商名称:会作为缺省安装目录的一部分,也建议采用全英文。

多语言

# At least one culture is needed. Supported culture can be found at:
# https://www.firegiant.com/wix/tutorial/user-interface/do-you-speak-english/
Localization:
-
  # Culture name
  Culture: 'en-us'
  # Product name in localized language
  ProductNameLoc: 'WiX Cover'
  # Manufacture name in localized language
  ManufacturerLoc: 'iCD'
  # License agreement terms in localized language, RTF format is needed.
  LicenseFile: 'license.rtf'
-
  Culture: 'zh-cn'
  ProductNameLoc: 'WiX Cover'
  ManufacturerLoc: 'iCD'
  LicenseFile: 'license.rtf'

根据需要增删多语言支持,但至少需要保留一种。具备多语言的安装包会根据Windows系统的语言设置,自动使用当前语言显示。为此,我们需要提供本地化的产品名称、生产商名称及用户许可协议文件。

文件

Files:
  # The files and directories in the installer package that will be installed on customers' computer.
  # Root folder itself will NOT be included.
  RootFolder: 'source'

  # The target file that the shortcuts point to. Relative path starting at the root folder defined above.
  MainExecutable: 'quickstart.txt'

  Icon:
    # The file providing application icon. Relative path starting at the root folder defined above.
    File: 'wixc.ico'
    Index: 0

文件部分主要用于指定哪些文件会被打包到安装包中。

  • 源文件根目录:这个目录(不包括自己)下的所有子目录及文件,都会被打包到安装包中,并保留目录结构。
  • 主可执行文件:这个文件有3个用处。
    • 快捷方式的目标地址
    • 安装过程中根据进程名自动终止旧版本应用进程
    • 安装结束后自动调起应用
    本例中,因为没有exe文件,所以使用了帮助文件。
  • 图标文件:图标用于快捷方式及应用卸载列表中。图标文件可以是ico或者exe文件,并标识出图标的序号(如果文件中只包含一个图标,就用0)。

注册表

Regs:
  # The directory containing exported registry files.
  RootFolder: 'installer\regs'

  # Set to 'true', all 'HKCU' and "HKLM" root path will be converted to 'HKMU'.
  ConvertToHKMU: true

支持扫描注册表导出文件(一般是.reg),将其中的信息包含到安装包中。

  • 注册表文件根目录:会扫描该目录下所有以.reg结尾的文件
  • 是否将注册表根目录自动转换为HKMU:我们在往注册表写数据时,一般会有两个根目录。HKCU代表当前用户,HKLM代表当前机器。安装包在安装时会有两种模式:安装到当前用户,或者当前机器(这个下边会讲)。如果将注册表数据的根目录改为HKMU,那就意味着安装包会根据安装模式,自动将注册表数据写到HKCUHKLM下。

环境变量

# Mirror of WiX environment element.
# Detail description of each attribute: https://wixtoolset.org/documentation/manual/v3/xsd/wix/environment.html
Envs:
-
  # Name of the environment variable
  Name: 'PATH'
  # create / set / remove
  Action: 'set'
  # yes / no
  Permanent: 'no'
  # yes / no. Caution: If set to 'yes', but install scope is current user, the installation will fail.
  System: 'no'
  # all / first / last
  Part: 'first'
  # The value to set into the environment variable
  Value: '[APPLICATIONFOLDER]'
  • Name:需要创建或者修改的环境变量名称。
  • Action:create - 创建;set -修改;remove -删除。
  • Permanent:如果选择no,那在卸载时,该环境变量不会被删除。
  • System:如果选择yes,则环境变量是指系统环境变量。
  • Part:all - 环境变量值等于新的环境变量值;first - 新的环境变量值附加到已有值的开始;last - 新的环境变量值附加到已有值的结尾
  • Value:新的环境变量值。本例中[APPLICATIONFOLDER]指最终的安装目录。

升级策略

Upgrade:
  # A lower version package can be installed or not.
  AllowDowngrades: false

  # The same version package can be installed or not.
  AllowSameVersionUpgrades: true
  • AllowDowngrades:在较新版本已经安装的情况下,是否允许用低版本覆盖。
  • AllowSameVersionUpgrades:是否允许用相同版本覆盖。

安装模式

InstallScope:
  # 'user': install just for current user
  # 'machine': install for all users of the machine
  # 'both': user can select the installation mode
  Mode: 'both'
  # the default mode if Mode = 'both'
  DefaultMode: 'user'
  • Mode:
    • user - 安装到当前用户下。默认的安装目录一般为c:\Users\<username>\AppData\Local\Apps\下。
    • machine - 安装到当前机器中,即当前机器中所有账号都能使用。默认的安装目录一般为c:\Program Files\下。
    • both - 两种方式都提供,用户在安装时选择。
  • DefaultMode:如果Modeboth时,缺省的安装模式。

终止已有进程

# Kill the process named by 'MainExecutable' during the installation to avoid penitential machine restart.
KillProcess: false

安装过程中自动终止旧版本应用进程,进程名是由前面设置的MainExecutable决定的。

调起应用

LaunchApplication:
  # Show a checkbox to launch the application after the installation if enabled.
  Enable: true

  # The checkbox is checked or not by default.
  CheckedByDefault: true
  • Enable:如果激活该配置,在安装结束后会增加一个选择框,用以选择是否调起安装的应用。
  • CheckedByDefault:选择框的缺省状态。

那现在整个配置文件就介绍完了。接下来我们可以生成安装包了,安装完WiX Cover后,打开一个Powershell窗口,执行以下命令:

wixc.ps1 -config some-path\my-config.yaml -output some-path\my-installer.msi

some-path\my-config.yaml是你自己的配置文件
some-path\my-installer.msi是最终生成的安装包文件

等命令执行完毕后,双击生成的msi文件看看效果吧。