利用Wix打包安装包

背景

将指定WPF项目利用Wix打包为安装包!

具体步骤

以打包名为 MRISoftwareDeployPlatform 的WPF项目为例,说明如何利用WIX将WPF打包为安装包。

1、安装 WiX Toolset 工具集

首先在GitHub发布页上下载并运行wix311.exe ,以部署 WiX Toolset 的构建环境。运行后点击中心的Install,安装成功后如下图

(注:此图)

2、安装 WiX Toolset 系列 Visual Studio 插件

打开Visual Studio,点击 扩展 -> 管理扩展 -> 搜索框输入 wix -> 点击 Wix Toolset Visual Studio Extension并进行下载,之后按照提示进行安装即可。
在这里插入图片描述

若安装时出现下图所示情况,个人建议利用Microsoft Visual Studio Installer Projects进行打包(具体操作可见博客 ),因为要解决这个问题可能涉及到CA许可证等文件,挺麻烦。
在这里插入图片描述

若是下图所示情况,直接点击Modify即可。
在这里插入图片描述

3、创建Wix工程

在目标项目下,右键点击解决方案 -> 添加 -> 新建项目 -> 输入wix -> 选择 Setup Project for Wix v3并创建。
[图片]

创建成功后,则如下图,此处创建的项目名为 MRIDPSetup,红框中内容为 Product.wxs 文件内容,而生成安装包则主要是在此文件上进行操作。
[图片]

4、添加工程文件

在 References 处添加相关文件。此处第一个需添加的是 MRISoftwareDeployPlatform 工程,因为其是项目,所以需在项目此页面进行选择,如图
[图片]

第二个则是WixUIExtension,此文件提供了安装时的UI引导页面,由于其是文件,因此需在上图的浏览项进行查找与选择,其路径大致为C:\Program Files (x86)\WiX Toolset v3.11\bin\WixUIExtension.dll ,可在相似路径下进行添加。
两个文件添加成功后如图:
[图片]

5、修改Product元素

根据需求,设置Product处的属性,如图
在这里插入图片描述

属性说明:
1)Id: 用于指定安装程序的 ProductCode,”*”指在构建安装程序时由 WiX 工具自动生成一个新的 GUID;
2)Name:为安装包名称,注册表也是保存当前配置;
3)Language:为区域性标志符(LCID),常见参数 1033 表示英语(美国),2052表示简体中文.以下是两种语言对应的Language与Codepage
在这里插入图片描述
4)Version:为安装包版本号;
5)Manufacturer:为生产厂商;
6)UpgradeCode:为升级编码,其内容格式为GUID,与上述Id的内容格式相同,便于后续配置升级策略。

6、修改Package元素

根据需求修改Package属性,修改后如下图:
[图片]

属性说明:
1) InstallerVersion:指定安装程序引擎的最低版本要求。”200”表示需要MSI 安装引擎Windows Installer 2.0 或更高版本;
2) Compressed: 指定是否要对安装包进行压缩,若为 yes,则安装包中的文件将被压缩;
3) InstallScope: 指定安装范围,值可选perMachine 或者 perUser,前者针对使用这个机器的所有用户,后者则针对安装包的运行用户;
4) Keywords: 指定与安装包相关的关键字,便于搜索和组织;
5) Comments: 提供对安装包的注释或说明。

7、修改MajorUpgrade元素

元素用于定义主要升级(Major Upgrade)的行为,常用于配置软件的升级策略。
因暂未涉及该需求,故而此处只需修改MajorUpgrade下的DowngradeErrorMessage属性。该属性用于指定在尝试安装较低版本的产品时显示的错误消息。可根据需求进行设计。此处修改内容如下

<MajorUpgrade DowngradeErrorMessage="A newer version of MRISoftwareDeployPlatform is already installed." />

8、修改Media属性

MediaTemplate 与 Media 元素的差别为: Media 元素用于定义实际的安装介质,而 MediaTemplate 元素则用于定义多媒体安装的模板,以便在构建过程中生成多个 Media 元素。
由于此处只需实现将存档文件(Cabinet 文件)嵌入到生成的安装包(MSI 文件)中,以保证安装文件的简洁,而该功能使用 Media即可实现,所以将注释掉原有的 MediaTemplate元素,并以 Media 进行替换。之后再将Media元素中的 EmbedCab 属性置为“yes”。修改结束后的代码如图,其中
在这里插入图片描述
在这里插入图片描述

9、设置安装引导界面

基础信息:
Wix提供了5种UI风格:WixUI_AdvancedWixUI_FeatureTreeWixUI_InstallDir (带有选择安装目录)、WixUI_Minimal (简洁安装) 和 WixUI_Mondo (自定义模块安装).可根据自己需求利用 UIRefe 进行声明使用.

Property 为安装配置特性,其中 Id: 属性的名称 ,Value: 属性的参数。

常用Id参数:
WIXUI_INSTALLDIR 安装默认路径;
WIXUI_EXITDIALOGOPTIONALTEXT 安装成功界面显示文字;
WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT 安装成功界面添加复选框(例如安装完成打开软件);
WixShellExecTarget 执行事件的目标,需要和执行事件一起使用,若不需要执行事件可不用在意此参数。

具体设置:在 Product 下添加上述信息,如图
[图片]

此处为了跳过许可协议这一引导界面,便采用了Publish(Publish 元素允许基于某些条件来触发或禁用特定的动作,从而实现根据用户的环境或选择进行动态控制的功能)进行操作,如上图,其中Order属性指定了页面的顺序,在WixUI_InstallDir 此风格下,许可协议这一页面处于第二顺序,所以此处手动设定以跳过此页面。

其实也可以通过这种方式去设置引导界面的先后顺序,只要知道目标UI风格下各页面的顺序便可进行相关操作。

10、添加WPF项目文件

wix打包时需要手动添加相关文件。此次的目标项目中,需要将一些脚本、python包安装包等文件进行打包,且需将其专门放置于一个文件夹(命名为“Scripts”)下,防止安装后文件过多影响使用。

一些元素说明:
(1)Feature 元素用于定义安装包中的功能,而功能是一组相关的组件,可选择性地安装或卸载。其中属性:
1)Id: 指定功能的唯一标识符;
2)Title: 指定用户界面中显示的标题;
3)Level: 指定功能的初始安装级别,0 表示未安装,1 表示安装;
4)ComponentGroupRef : 引用一个组件组,将该组件组包含在当前功能中。组件组是一组相关的组件的集合,它们可以一起进行安装或卸载。其通常与 ComponentGroup对应,前者为引用,后者为本体;
5)ComponentRef : 引用一个单独的组件,将该组件包含在当前功能中。其与Component对应。

(2)Fragment 元素是 WiX 中用于组织代码、实现模块化和条件设置的关键元素之一。该元素内部可以包含对其他文件或外部模块定义的组件的引用,通过这种方式将不同的组件组织在一个逻辑单元内。

通过合理使用 元素,可以使 WiX 项目更加清晰、可维护,并支持更灵活的构建和条件性添加组件的需求。
如下图,其中var.MRISoftwareDeployPlatform.TargetDir则指代了目标安装路径,此参数的值是需要在安装时手动选择后才可最终确定。图中ProductComponents在wix项目中默认存在,其保存的是WPF项目相关的exe和dll,而Scripts则保存的是脚本与python包安装文件。
如图所示:
在这里插入图片描述

11、添加桌面快捷方式

此处使用的是Directory进行快捷方式添加。先在Feature 中添加DesktopFolderShortcut,此为桌面快捷方式。
之后在Id为 TARGETDIR 的 Directory节点 中设置具体内容。节点说明:
1)DesktopFolder 指桌面文件夹,Windows默认值
2)Shortcut 节点表示快捷方式

  • Id: 唯一标识
  • Name: 快捷方式名称
  • Description: 快捷方式描述
  • Target: 快捷方式目标文件
  • WorkingDirectory:指工作区域
  • Arguments: “/x [ProductCode]”,是传递给目标文件的命令行参数。[ProductCode] 会在运行时被替换为当前安装的产品代码。

3)RemoveFolder 用于在卸载时删除指定的目录

  • Id: 指定要删除的目录的标识符。
  • On: 指定在何时执行删除操作。在这个例子中,On=“uninstall” 意味着在执行卸载操作时执行删除操作。

4)RegistryValue 用于在注册表中设置一个值

  • Root: 指定注册表项的根键。
  • Key: 指定注册表项的路径。
  • Name: 指定注册表项的名称。
  • Type: 指定注册表项的数据类型。
  • Value: 指定注册表项的值。
  • KeyPath: 指定是否将该注册表项视为产品的关键路径,用于检测产品是否已安装。

具体代码设置如下
[图片]

12、添加菜单快捷方式

与桌面快捷方式不同,创建菜单快捷方式时需要在菜单目录下添加一个目录(可根据自己需求设置)。相较于桌面快捷方式,首先需更换目标路径,即ProgramMenuFolder表示菜单目录,而菜单快捷方式的其他设置类似于桌面快捷方式,具体可查看下图。但下图中还添加了一个卸载快捷方式,同存于所添加的目录下。

其中,msiexec.exe是Windows系统自带的卸载软件,而 [SystemFolder] 则指代Windows默认系统路径;Arguments属性的设置中,[ProductCode]指代了当前这个wix项目生成后的Code信息,msiexec.exe主要是通过此Code信息来指定卸载安装后的软件。
在这里插入图片描述

13、设置安装引导界面语言环境

wix项目生成的安装包默认是英文环境,为满足大众需求,通常需要将其转换为中文环境。
首先在wix项目下添加一个 Localization File,命名为WixUI_zh-cn. 此类文件,即Wxl文件相当于应用程序的资源文件。

之后设置WixLocalization节点属性,中文的Codepage 为 936, Culture为 zh-cn。

再如图进行设置,其中 Overridable 设为 yes,则表示可以重写。因为默认是英文,可以重写的意思就是最新的String会覆盖之前的同名Id。
[图片]

14、最后设置

若未进行第8步骤的操作,则整个wix项目生成后会输出三个文件,即
(1)MSI 文件 (.msi):
作用: MSI 文件是最终生成的安装包,包含了应用程序的安装信息、文件、注册表设置、服务等。它是 Windows Installer 技术的标准安装包格式。当用户运行 MSI 文件时,Windows Installer 服务会负责将应用程序正确地部署到计算机上,并执行必要的配置和安装步骤。MSI 文件是用于实际部署应用程序的主要文件。用户可以通过双击 MSI 文件来安装、修复、卸载应用程序。

(2)CAB 文件:
作用: CAB 文件是压缩文件,其中包含了在安装期间需要的文件。这些文件可能包括应用程序的二进制文件、资源文件等。CAB 文件通常用于减小 MSI 文件的大小,提高传输效率。 当用户运行 MSI 文件时,其中的 CAB 文件会被提取,并包含的文件将被解压缩到计算机上。这有助于减少网络传输时间和占用磁盘空间。

(3)WiXPDB 文件 (.wixpdb):
作用: WiXPDB 文件是 WiX 项目的构建数据库文件,包含了 WiX 项目的构建信息、源文件列表、目标文件等。这个文件对于调试和了解 WiX 项目的结构和构建过程非常有用。WiXPDB 文件主要用于开发人员进行调试和分析构建过程。虽然不是必需的,但在需要深入了解项目的构建细节时,这个文件可以提供有用的信息。

而进行了第8步骤中所说的内容,则cab文件会被集成到msi文件中。此时项目生成后的文件则还有一个wixpdb文件。
为了降低文件数量,还需在项目属性界面的Build下勾选Suppress output of the wixpdb files,如图,此操作会禁止输出wixpdb文件。如此,项目生成后则会只有一个msi文件。
[图片]

源码

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
        <Product Id="*" Name="MRIDPSetup"
                         Language="2052"
                         Codepage="936"
                         Version="1.0.0.0"
                         Manufacturer="xxxxxx"
                         UpgradeCode="05edbaec-c8fb-4bab-82ff-1fa75a55cd10">

                <Package InstallerVersion="200"
                                 Compressed="yes"
                                 InstallScope="perMachine"
                                 Keywords="MRIDP"
                                 Comments="xxxxxxxxxx"/>

                <MajorUpgrade DowngradeErrorMessage="A newer version of MRISoftwareDeployPlatform is already installed." />
                <!--<MediaTemplate />-->
                <Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />


                <Feature Id="ProductFeature" Title="MRIDPSetup" Level="1">
                        <ComponentGroupRef Id="ProductComponents" />
                        <ComponentGroupRef Id="Scripts" />
                        <ComponentRef Id="ApplicationShortcut" />
                        <ComponentRef Id="DesktopFolderShortcut" />
                </Feature>

                <UI>
                        <UIRef Id="WixUI_InstallDir" />
                        <Publish Dialog="WelcomeDlg" Control="Next"        Event="NewDialog" Value="InstallDirDlg" Order="1">1</Publish>
                        <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="3">1</Publish>
                </UI>

                <Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
                <Property Id="WIXUI_EXITDIALOGOPTIONALTEXT" Value="Thank you for installing this product." />
                <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch this Application " />
                <UIRef Id="WixUI_Common" />
        </Product>

        <Fragment>
                <Directory Id="TARGETDIR" Name="SourceDir">
                        <Directory Id="ProgramFilesFolder">
                                <!-- 在安装路径下添加Scripts文件夹 -->
                                <Directory Id="INSTALLFOLDER" Name="MRIDPSetup">
                                        <Directory Id="Scripts" Name="Scripts"/>
                                </Directory>
                        </Directory>

                        <!-- 添加菜单栏快捷方式 -->
                        <Directory Id="ProgramMenuFolder">
                                <Directory Id="ApplicationProgramsFolder" Name="MRISoftwareDeployPlatform">
                                        <Component Id="ApplicationShortcut" Guid="*">
                                                <Shortcut Id="ApplicationStartMenuShortcut" Name="MRISoftDP"
                                                                  Description="xxxxxxxxx"
                                                                  Target="[INSTALLFOLDER]MRISoftwareDeployPlatform.exe"
                                                                  WorkingDirectory="INSTALLFOLDER">
                                                </Shortcut>
                                                <Shortcut Id="ApplicationUninstallShortcut"
                                                  Name="Uninstall"
                                                  Description="Uninstall"
                                                  Target="[SystemFolder]msiexec.exe"
                                                  Arguments="/x [ProductCode]"/>
                                                <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
                                                <RegistryValue Root="HKCU" Key="Software\Microsoft\MRISoftwareDeployPlatform" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
                                        </Component>
                                </Directory>
                        </Directory>

                        <!-- 添加桌面栏快捷方式 -->
                        <Directory Id="DesktopFolder">
                                <Component Id="DesktopFolderShortcut" Guid="*">
                                        <Shortcut Id="AppDesktopShortcut" Name="MRISoftDP"
                                                          Description="xxxxxxxx"
                                                          Target="[INSTALLFOLDER]MRISoftwareDeployPlatform.exe"
                                                          WorkingDirectory="INSTALLFOLDER">
                                        </Shortcut>
                                        <RemoveFolder Id="DesktopFolder" On="uninstall"/>
                                        <RegistryValue Root="HKCU" Key="Software\Neusoft_MR\MRISoftwareDeployPlatform" Name="installed" Type="integer" Value="1" KeyPath="yes" />
                                </Component>
                        </Directory>
                </Directory>

        </Fragment>

        <Fragment>
                <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
                        <Component Id="ProductComponent" Guid="{7B576F74-DE0A-4125-90A2-AF83FD9891B0}">
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)MRISoftwareDeployPlatform.exe" Id="MRISoftwareDeployPlatform.exe"/>
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)MRISoftwareDeployPlatform.exe.config" Id="MRISoftwareDeployPlatform.exe.config"/>
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)Newtonsoft.Json.dll" Id="Newtonsoft.Json.dll"/>
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)System.Buffers.dll" Id="System.Buffers.dll"/>
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)System.Memory.dll" Id="System.Memory.dll"/>
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)System.Numerics.Vectors.dll" Id="System.Numerics.Vectors.dll"/>
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)System.Runtime.CompilerServices.Unsafe.dll" Id="System.Runtime.CompilerServices.Unsafe.dll"/>
                        </Component>
                </ComponentGroup>
                <ComponentGroup Id="Scripts" Directory="Scripts">
                        <Component Id="Scripts" Guid="{4F3A2FE1-6190-4A32-8D8C-594DCB527480}">
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)Scripts\demjson-2.2.4.tar.gz" Id="demjson_2.2.4.tar.gz"/>
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)Scripts\InstallPythonPackages.bat" Id="InstallPythonPackages.bat"/>
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)Scripts\jsonpath_ng-1.5.3-py3-none-any.whl" Id="jsonpath_ng_1.5.3_py3_none_any.whl"/>
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)Scripts\jsonpath-0.82.2.tar.gz" Id="jsonpath_0.82.2.tar.gz"/>
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)Scripts\KillAll.ps1" Id="KillAll.ps1"/>
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)Scripts\pip-19.3.1-py2.py3-none-any.whl" Id="pip_19.3.1_py2.py3_none_any.whl"/>
                                <File Source="$(var.MRISoftwareDeployPlatform.TargetDir)Scripts\pyodbc-4.0.30-cp36-cp36m-win_amd64.whl" Id="pyodbc_4.0.30_cp36_cp36m_win_amd64.whl"/>
                        </Component>
                </ComponentGroup>
        </Fragment>
</Wix>


  • 15
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值