[译]:WiX Toolset入门——安装包捆版包基础元素介绍
博客分类: 官方教程
返回目录索引
本文内容为官方文档多部分整合:
原文链接:
在本节中,我们将介绍使用WiX Toolset创建简单的安装包捆绑包的基础知识。
捆绑包是将多个安装包的集合到一个安装包进行安装。捆绑包常用于安装一个.msi应用的先决条件,例如.NET Framework或Visual C++ Runtime。捆绑包还允许将大型应用或应用套件拆分为小型的逻辑安装包,但在给最终用户时,仍然可以是单个产品。
为了为多个安装包提供无缝的安装体验,WiX toolset提供了一个名为Burn的引擎(通常是一个bootstrapper或chainer)。Burn引擎是一个可执行文件,它托管了一个名为bootstrapper应用的dll。bootstrapper应用dll负责用最终用户呈现UI,以及控制Burn引擎何时进行下载、安装、修复和卸载操作。大部分开发者不许与Burn引擎打交道,因为WiX toolset提供了一个标准的bootstrapper应用以及其创建捆绑包所需的语言。
下面将会介绍WiX 捆绑包语言以及如何使用它来创建捆绑包。
创建捆绑包基础结构
本节元素索引:
<Bundle>
、<WiX>
、<BootstrapperApplicationRef>
、<Chain>
、<Variable>
。
捆绑包中的根元素是<Bundle>
。<Bundle>
元素是<WiX>
元素的直接子节点。下面是一个空捆绑包示例:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Bundle>
<!-- Contents of the bundle goes here -->
</Bundle>
</Wix>
在以下示例中,我们会为<Bundle>
元素添加以下元素:
<BootstrapperApplicationRef>
<Chain>
<Variable>
首先,为<Bundle>
添加两个最常用的元素,示例如下:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Bundle>
<BootstrapperApplicationRef />
<Chain>
</Chain>
</Bundle>
</Wix>
<BootstrapperApplicationRef>
元素最终会指向WiX toolset提供的标准Bootstrapper应用,而<Chain>
元素最终是包含要打包到一起的安装包列表。
现在你有一个基础的Bundle结构,参见下一节继续为<BootstrapperApplicationRef>
元素添加信息。
为捆绑包添加Bootstrapper应用处理
本节元素索引:
<BootstrapperApplication>
、<BootstrapperApplicationRef>
、<Framement>
、<PayloadGroup>
。
每一个捆绑包都需要一个bootstrapper应用来驱动Burn引擎。<BootstrapperApplication>
元素用于定义一个新的bootstrapper应用。<BootstrapperApplicationRef>
元素则用于指向已有的bootstrapper应用 —— 在<Framement>
中定义或在WiX扩展里。
WiX标准Bootstrapper应用在WixBalExtension.dll中。下面展示如何使用捆绑包:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Bundle>
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
</Chain>
</Bundle>
</Wix>
WiX标准Bootstrapper应用可能无法满足专业捆绑包所需的所有功能要求,所以这时需要开发自定义的bootstrapper应用dll。以下是如何使用自定义dll,假设我们创建了一个名为ba.dll的bootstrapper应用:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Bundle>
<BootstrapperApplication SourceFile="path\to\ba.dll" />
<Chain>
</Chain>
</Bundle>
</Wix>
在<BootstrapperApplication>
元素和<BootstrapperApplicationRef>
元素中,你可能需要附加payload文件,如:bootstrapper应用dll所需要的资源文件。
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Bundle>
<BootstrapperApplication SourceFile="path\to\ba.dll">
<Payload SourceFile="path\to\en-us\resources.dll" />
<PayloadGroupRef Id="ResourceGroupforJapanese" />
</BootstrapperApplication>
<Chain>
</Chain>
</Bundle>
</Wix>
此示例中引用了一个名为resources.dll的本地payload文件,以及一个payload文件组 —— 使用<PayloadGroup>
元素在其他位置的Framement
中定义。
编辑捆绑包中的内容(安装包)清单
本节元素索引:
<Chain>
、<Fragment>
、<PackageGroupRef>
。
为了让Bundle可以使用任何包,则需要针对包写出描述包的定义。它可以直接写在Bundle中的<Chain>
元素下面,也可以写在一个<Fragment>
中,然后利用<PackageGroudRef>
将它引用到Bundle的<Chain>
中使用。其中后一种方法,可以用来在各个捆绑包之间共享同一个包定义。
WiX架构支持链接以下包类型:
以下是一个包含ExePackage的共享片段示例:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="MyPackage">
<ExePackage
SourceFile="[sources]\packages\shared\MyPackage.exe"
DetectCondition="ExeDetectedVariable"
DownloadUrl="http://example.com/?mypackage.exe"
InstallCommand="/q /ACTION=Install"
RepairCommand="/q ACTION=Repair /hideconsole"
UninstallCommand="/q ACTION=Uninstall /hideconsole" />
</PackageGroup>
</Fragment>
</Wix>
现在你可以为安装包添加安装条件 —— 只能在x86 Windows XP及以上的系统中安装。WiX中含有一些内置变量,可以用来创建条件语句。下面示例中InstallCondition="NOT VersionNT64 AND VersionNT >= v5.1"
即表示如何利用内置变量创建条件:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="MyPackage">
<ExePackage
SourceFile="[sources]\packages\shared\MyPackage.exe"
DetectCondition="ExeDetectedVariable"
DownloadUrl="http://example.com/?mypackage.exe"
InstallCommand="/q /ACTION=Install"
RepairCommand="/q ACTION=Repair /hideconsole"
UninstallCommand="/q ACTION=Uninstall /hideconsole"
InstallCondition="NOT VersionNT64 AND VersionNT >= v5.1" />
</PackageGroup>
</Fragment>
</Wix>
其中VersionNT属性支持4段的版本号([Major].[Minor].[Build].[Revision])。有关Windows操作系统的主要版本和次要版本列表见:Operating System Version。
另外,你也可以在里面定义自己的变量,并保存搜索结果。更多内容见本文的后续部分。
捆绑包内置变量
Burn引擎中提供了一组常用的变量,这样我们直接使用它们,而不用自定义变量。下面是内置变量列表:
变量名 | 用途 |
---|---|
AdminToolsFolder | 获取文件夹 CSIDL_ADMINTOOLS . |
AppDataFolder | 获取文件夹 CSIDL_APPDATA . |
CommonAppDataFolder | 获取文件夹 CSIDL_COMMON_APPDATA . |
CommonFilesFolder | 获取文件夹 CSIDL_PROGRAM_FILES_COMMONX86 . |
CommonFiles64Folder | 获取文件夹 CSIDL_PROGRAM_FILES_COMMON . |
CommonFiles6432Folder | 在64位Windows上获取文件夹 CSIDL_PROGRAM_FILES_COMMON 和在32位Windows上获取文件夹CSIDL_PROGRAM_FILES_COMMONX86 . |
CompatibilityMode | 如果需要以兼容模式启动引导程序,此值非零。 |
ComputerName | 由GetComputerName()方法返回的计算机名称。 |
Date | 获取用户本地日期,格式为短日期格式。 |
DesktopFolder | 获取文件夹 CSIDL_DESKTOP . |
FavoritesFolder | 获取文件夹 CSIDL_FAVORITES . |
FontsFolder | 获取文件夹 CSIDL_FONTS . |
InstallerName | 获取安装包引擎名称("WiX Burn"). |
InstallerVersion | 获取安装包引擎版本 |
LocalAppDataFolder | 获取文件夹 CSIDL_LOCAL_APPDATA . |
LogonUser | 获取当前用户名 |
MyPicturesFolder | 获取文件夹 CSIDL_MYPICTURES . |
NTProductType | 从操作系统版本信息中获得的数字产品类型 |
NTSuiteBackOffice | 如果操作系统版本套件是Back Office,则此值非零 |
NTSuiteDataCenter | 如果操作系统版本套件是Datacenter,则此值非零 |
NTSuiteEnterprise | 如果操作系统版本套件是Enterprise,则此值非零 |
NTSuitePersonal | 如果操作系统版本套件是Personal,则此值非零 |
NTSuiteSmallBusiness | 如果操作系统版本套件是Small Business,则此值非零 |
NTSuiteSmallBusinessRestricted | 如果操作系统版本套件是Restricted Small Business,则此值非零 |
NTSuiteWebServer | 如果操作系统版本套件是Web Server,则此值非零 |
PersonalFolder | 获取文件夹 CSIDL_PERSONAL . |
ProcessorArchitecture | 获取本机的计算机信息,内容详见:[SYSTEM_INFO.wProcessorArchitecture][023] |
Privileged | 如果进程可以提升权限(Vista+)或者以管理员身份运行(WinXP),则此值非零。 |
ProgramFilesFolder | 获取文件夹 CSIDL_PROGRAM_FILESX86 . |
ProgramFiles64Folder | 获取文件夹 CSIDL_PROGRAM_FILES . |
ProgramFiles6432Folder | 在64位Windows上获取文件夹 CSIDL_PROGRAM_FILES 和在32为Windows上获取文件夹CSIDL_PROGRAM_FILESX86 |
ProgramMenuFolder | 获取文件夹 CSIDL_PROGRAMS . |
RebootPending | 如果需要系统重启,则此值非零。注意:在第一次请求此变量时,系统返回的为已经重启过的状态。 |
SendToFolder | 获取文件夹 CSIDL_SENDTO . |
ServicePackLevel | 操作系统已经安装的服务包的数值。 |
StartMenuFolder | 获取文件夹 CSIDL_STARTMENU . |
StartupFolder | 获取文件夹 CSIDL_STARTUP . |
SystemFolder | 获取文件夹 CSIDL_SYSTEMX86 . |
SystemLanguageID | 获取系统语言环境的语言ID |
TempFolder | 获取临时文件夹位置 |
TemplateFolder | 获取文件夹 CSIDL_TEMPLATES . |
TerminalServer | 如果系统是以远程桌面服务的服务器模式下运行应用,此值非零。 |
UserLanguageID | 获取当前用户语言环境的语言ID |
VersionMsi | Windows Installer引擎版本的版本值 |
VersionNT | 操作系统版本的版本值。其结果是一个版本变量(v#.#.#.#),它不同于MSI属性中的整数形式的VersionNT 。例如,在Bundle条件中变量设置为:"VersionNT > v6.1". |
VersionNT64 | 64位操作系统版本的版本值。在32位操作系统中此值未定义。其结果是一个版本变量(v#.#.#.#),它不同于MSI属性中的整数形式的VersionNT64 。例如,在Bundle条件中变量设置为:"VersionNT64 > v6.1". |
WindowsFolder | 获取文件夹 CSIDL_WINDOWS . |
WindowsVolume | 获取窗口音量文件夹 |
WixBundleAction | 从命令行中设置为BOOTSTRAPPER_ACTION数值,并在调用IBootstrapperEngine::Plan()时更新. |
WixBundleDirectoryLayout | 使用-layout 设置文件夹来源(默认是包含exe捆绑包文件的目录)。此变量还可以通过bootstrapper应用修改设置文件的位置配置。 |
WixBundleElevated | 获取捆绑包有没有提升权限,一旦提升权限,此值被设置为1。例如,使用此变量控制在bootstrapper应用UI上显示或隐藏提升权限保护。 |
WixBundleExecutePackageCacheFolder | 获取当前正在执行的包的缓存文件夹的绝对路径。此变量只有在包运行的时候有效。 |
WixBundleForcedRestartPackage | 获取要求使用时必须重启的包ID。此值会在下次调用时重置。 |
WixBundleInstalled | 获取捆绑包是否已经安装。此值仅在引擎初始化时设置。 |
WixBundleLastUsedSource | 获取最后一个成功的加载源的路径。 |
WixBundleName | 获取捆绑包的名称(Bundle/@Name)。此变量可以在Bootstrapper应用运行时修改捆绑包的名称来设置。 |
WixBundleManufacturer | 获取捆绑包的制造商(Bundle/@Manufacturer). |
WixBundleOriginalSource | 获取捆绑包最初运行的源路径。 |
WixBundleOriginalSourceFolder | 获取捆绑包最初运行的源文件夹。 |
WixBundleSourceProcessPath | 获取捆绑包最初执行的源路径。只有在纯净环境下执行才会设置。 |
WixBundleSourceProcessFolder | 获取捆绑包最初执行的源文件夹。只有在纯净环境下执行才会设置。 |
WixBundleProviderKey | 获取捆绑包依赖程序的key |
WixBundleTag | 获取捆绑包中开发人员定义的标签字符串(Bundle/@Tag). |
WixBundleUILevel | 获取UI级别(BOOTSTRAPPER_DISPLAY枚举值). |
WixBundleVersion | 获取捆绑包的版本(Bundle/@Version). |
利用变量定义/存储搜索
搜索功能是用于检测目标机器是否满足一定条件。搜索的结果存储在一个变量中。然后利用变量构建安装条件。搜索的架构位于WixUtilExtension中。以下为支持的搜索列表:
搜索可以依赖于其他搜索的结果。注意,所有的搜索都在WiXUtilExtension中。因此,你需要在代码中添加WiXUtilExtension的命名空间。下面为示例代码:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Fragment>
<util:RegistrySearch Id="Path"
Variable="UniqueId"
Root="HKLM,SOFTWARE\Microsoft\MyProduct\Unique Id\"
Key="Product"
Result="Value" />
<util:RegistrySearch
Variable="patchLevel"
Root="HKLM,SOFTWARE\Microsoft\MyProduct\[UniqueId]\Setup"
Key="PatchLevel"
Result="Exists"
After="Path" />
</Fragment>
</Wix>
在将搜索定义好后,并将其存储到变量中,就可以将变量用于安装条件了。例如,你可以为你的安装包添加搜索和安装条件来使用安装条件中的注册表搜索结果。下面示例包含了条件和搜索定义的完整的代码片段:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Fragment>
<util:RegistrySearch Id="Path"
Variable="UniqueId"
Root="HKLM,SOFTWARE\Microsoft\MyProduct\Unique Id\"
Key="Product"
Result="Value" />
<util:RegistrySearch
Variable="patchLevel"
Root="HKLM,SOFTWARE\Microsoft\MyProduct\[UniqueId]\Setup"
Key="PatchLevel"
Result="Exists"
After="Path" />
<PackageGroup Id="MyPackage">
<ExePackage
SourceFile="[sources]\packages\shared\MyPackage.exe"
DownloadURL="http://mywebdomain.com/?mypackage.exe"
InstallCommand="/q /ACTION=Install"
RepairCommand="/q ACTION=Repair /hideconsole"
UninstallCommand="/q ACTION=Uninstall /hideconsole"
InstallCondition="x86 = 1 AND OSVersion >= v5.0.5121.0 AND patchLevel = 0" />
</PackageGroup>
</Fragment>
</Wix>
现在,你有一个完全定义的代码片段,且它可以共享给其他包使用。关于更多链接包内容见下节。
在捆绑包中链接包
要链接一个包,可以直接写在Bundle中的<Chain>
元素下面,也可以写在一个<Fragment>
中,然后利用<PackageGroudRef>
将它引用到Bundle的<Chain>
中使用。其中后一种方法,可以用来在各个捆绑包之间共享同一个包定义。
以下为直接定义到<Chain>
中的代码示例:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Bundle>
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<ExePackage
SourceFile="path\to\MyPackage.exe"
DownloadUrl="http://example.com/?mypackage.exe"
InstallCommand="/q /ACTION=Install"
RepairCommand="/q ACTION=Repair /hideconsole" />
</Chain>
</Bundle>
</Wix>
以下为引用共享包定义的示例:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Bundle>
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<PackageGroupRef Id="MyPackage" />
</Chain>
</Bundle>
</Wix>
至此,捆绑包的基础元素就讲完了。后面将会是捆绑包的使用内容。
译:奇葩史