在讲windows installer xml 描述文件之前, 首先讲讲Windows Installer(以前是Microsoft installer 所以有简写MSI,后来改名Windows Installer, 但仍然使用使用大家熟悉的msi后缀)。 Windows Installer改变了软件安装的方式,以前的大多数的安装软件所做的仅仅是拷贝文件和写注册表,而通常不会去关心系统是否已经装有什么。Windows Installer 把软件分成“Product”(比如像Office这样的软件),“features”(软件中的模块,比如office中的word等),以及“Components”(功能单元,比如动态库,ocx以及特定的注册表记录)。 Windows Installer 的主要特点有:
- 通过components来管理共享文件
- components的自动修复
- 完全干净的卸载以及安装
- 完全回滚防止失败的安装
- 在锁定权限的系统上通过提升权限安装
Windows Installer 架构 MSI(Windows Installer 文件格式)其本质是一个数据,描述一个软件如何安装,以及把软件分成几个部分,比如上面提到的Product,Component等等。MSI文件与软件源文件一起提供了软件的所有信息。数据库的格式是在安装的时候记录到安装电脑上的,也就是说修复软件的所有信息随时都保存着。 下面仔细说下Windows Installer XML文件 Windows Installer xml,即Wix文件,提供了一种描述Windows 安装数据库(MSI,MSM)的机制,以及提供了把xml描述文件转换成可用数据库的工具。这个机制的第二个版本,wix.xsd,提供了一些额外的内容来简化从一组xml文档转化成多个Windows安装数据库的过程。
- .wxs以及.wixobj (Windows Installer Xml 文件)
wxs扩展名表示了Windows Intaller Xml。wxs 文件首先会被预处理然后编译成wixobj后缀的文件。当所有的源文件都被编译成了目标文件,链接程序就会链接所有的目标文件然后生成Windows Installer 数据库。编译和链接的详细内容文件后面将会讨论。
- wxs文件的结构
所有的wxs文件都是一个很规范的xml文件。其包括根元素<Wix/>。在预编译之前,其他的源文件可以也可以不遵守WiX机制。但是在预编译之后,所有的源文件都必须遵守WiX机制,不然就不能通过编译了。 根元素<wix/>最多只能包含下面两个元素之一来作为其子元素,这两个元素是:<product/>和<module/>。然而,<Fragment/>元素的个数却可以是没有限制的。但源文件被编译到目标文件时,这些元素的每个实例都会在目标文件中生成一个新的区(section)。因此,这三个元素通常被认作是区(section)元素。 这里必须主要到,每个源文件中只能够有<Product/>或者<Module/>元素中的一个作为其区元素,因为他们会被编译成特殊的区,这些区被称为记录区(Entry Section)。记录区被用来作为链接过程中的开始位置。区、记录区、以及整个链接过程这些具体内容会在本文中加以详细介绍。 区元素的子元素定义了Windows Installer 数据库的内容。<Property/>元素把目录映射到Property表中,而<Directory/>元素把建立起整个目录(Directory)表。所有的元素都包含一个Id属性,用来作为数据库中记录的主键。注意,在WiX机制的最初版本中,主键是由元素的文本信息表示的,而不用这个位置去表示主键原因很多的,所以最后用Id属性取而代之。在大多数情况下,但源文件呗编译成目标文件时,Id属性也同样定义了一个符号信息。
- 符号与引用
目标文件中的每个符号都有元素名和Id属性中提取出来的唯一标识所组成。符号信息很重要的原因是他能够被其他源文件的区所引用。比如,在<Directory/>结构能够在一个源文件的<Fragment/>元素中所定义,并且<Component/>元素也能够在不同的源文件的<Fragment/>中去定义。通过给<Component/>元素建立父元素<DirectoryRef/>就能建立一个显式的引用,这个引用能够引用到在第一个源文件中所定义的符号。然后,链接器就能把所有定义的符号和引用链接起来做成一个Windows安装数据库。在一些情况下,隐式的引用会在编译器处理源文件的时候有编译器生成。这些隐式的引用于显式的引用是完全一样的。 除了上面描述的简单引用,Wix还提供了特别的复杂的引用。复杂引用会在链接器必须产生额外信息去链接符号和引用在一起的时候来使用。复杂引用最直接的例子就是Windows安装的Feature和Component的关系。但一个<Componet/>元素被显式地由<Featrue/>元素通过<ComponentRef/>引用时,链接器就必须得到<Feature/>的符号以及<Component/>的符号,并在FeatureComponents表中添加一个记录。 Feature和Component的关系可以更为复杂,因为在<Component/>中的特定元素,比如<Shortcut/>,可以向上引用到与这个Component相关的主Feature。这些从<Component>元素的孩子元素引用被称作反引用,有时也叫做特征反链接(feature backlinks)。处理复杂引用以及反引用可能是链接器要做的最为复杂的事情。 注意,处理符号的定义以及引用时在Wix工具集的第二个版本才有的。以前,有个必要的工作是把<Component>打包到成整合的模块,然后利用这个整合的步骤来做初步符号链接。新的系统对于定义链接变得更为灵活,避免了需要去保证整合模块的每个记号必须是唯一的这个多余开销。
- .wixobj文件结构
wixobj文件给每个源文件编译后建立的。wixobj文件是xml文档,参照在Wix项目中定义的objects.xsd机制。正如上面粗略描述,可以知道包含一个或多个区,同样还包含符号以及多其他符号的引用。 尽管符号和引用可以说是wixobj文件中最重要的数据,但是他们并非存储真正的信息。相反,wixobj文件很大部分是由<table/>、<row/>以及<field/>元素组成,这些元素提供存储在Windows安装数据库的原始数据。在很多情况下,链接器不光要处理符号以及引用信息,还要利用在Wixobj的原始数据并对这些数据做更新。 我们可以有趣地发现,目标文件机制,即objects.xsd,使用了camel命名方法,而源文件机制,即wix.xsd使用了Pascal命名方式。这是个明智的做法,因为其可以提示目标文件不是拿来给用户编辑用的。而实际上,所有定义由Wix工具处理数据的所有机制都使用camel命名方式。
- candle–WindowsInstallerXML编译器
candle.exe是Windows Installer XML编译器。其负责预处理输入的.wxs文件,根据Wix机制wix.xsd生成合法地、结构完好的XML文档。然后,每个以前期处理的源文件被编译成.wixobj文件。 编译过程相对来说是直接明了。Wix机制把自身变成一个简单的递归回溯解析器。编译器处理每个元素时同时生成新的符号,并计算必要的引用以及产生原始数据到.wixobj文件中去。 candle的第二个版本相对于第一个来说没有太多不同。任何改变都会由建立新的符号和引用链接或者给予用户的反馈设置而引起。两个版本的不同之处是:新的目标文件格式是XML而非MSI,主键的模块化在链接是发生、以及二进制流的引入出现在链接的时候。
- light – Windows Installer XML 链接器
light.exe 是Windows Installer XML链接器,其负责处理一个或多个.wixobj文件,接收各种外部文件的元数据,然后构建出Windows安装数据库(MSI或者MSM)。必要的时候,light会创建cabinet,并嵌入流到创建的Windows安装数据库中。 链接器的工作首先是通过到命令行中提供的目标文件集合中搜索从而找出记录区。如果超过一个记录去被找到,light将出现错误并终止。这个终止是必要的,因为记录区定义了什么样的Windows安装数据库(MSI<Product>或者MSM<Module/>)将要被创建。从一个链接操作中构建出两个数据库是不可能的。 尽管链接器定义记录去,但定义在每个目标文件中的符号却在符号表中记录。在记录区被找到之后,链接器就会试着通过查找符号表来解析所有在区中的引用。但一个符号在不同的去被查找到时,链接就会递归的解析在这个新区里面的引用。整合不同的区这个步骤对解析所有引用很有必要,这个步骤会一直执行到所有的引用都被解析完。如果一个符号无法再所有的目标文件中查找到,那么链接器就会因为符号没有定义而运行截止。 在所有的区都被找到,复杂和逆引用就会进行。 一旦所有的引用都被找到,就会处理所有的行,。。。。。。。。。。。。。
- 使用wix生成msi文件,可以参考链接。