# 34.1. `msilib` - 读取和写入Microsoft安装程序文件

源代码： Lib / msilib / __ init __。py

`msilib`支持创建Microsoft Installer（`.msi`）文件。因为这些文件通常包含嵌入的“cabinet”文件（`.cab`），所以它还公开了一个API来创建CAB文件。支持读取`.cab`文件目前未实现；可以读取对`.msi`数据库的支持。

此包旨在提供对`.msi`文件中所有表的完全访问，因此，它是一个相当低级的API。此包的两个主要应用程序是`distutils`命令`bdist_msi`和创建Python安装程序包本身（虽然目前使用不同版本的`msilib`

包内容可大致分为四个部分：低级CAB例程，低级MSI例程，更高级MSI例程和标准表结构。

`msilib.``FCICreate`(cabname, files)

  创建名为cabname的新CAB文件。文件必须是元组列表，每个元组包含磁盘上文件的名称和CAB文件中的文件名称。

  这些文件将按照它们在列表中显示的顺序添加到CAB文件。使用MSZIP压缩算法将所有文件添加到单个CAB文件中。

  目前没有公开回调到Python的MSI创建的各个步骤。

`msilib.``UuidCreate`()

  返回新的唯一标识符的字符串表示形式。它包装Windows API函数`UuidCreate()`和`UuidToString()`。

`msilib.``OpenDatabase`(path, persist)

  通过调用MsiOpenDatabase返回一个新的数据库对象。path是MSI文件的文件名； persist可以是常数`MSIDBOPEN_CREATEDIRECT`，`MSIDBOPEN_CREATE`，`MSIDBOPEN_DIRECT`，`MSIDBOPEN_READONLY`或`MSIDBOPEN_TRANSACT`，并且可以包括标志`MSIDBOPEN_PATCHFILE`。有关这些标志的含义，请参阅Microsoft文档；根据标志，打开现有数据库或创建新数据库。

`msilib.``CreateRecord`(count)

  通过调用`MSICreateRecord()`返回一个新的记录对象。count是记录的字段数。

`msilib.``init_database`(name, schema, ProductName, ProductCode, ProductVersion, Manufacturer)

  Create and return a new database name, initialize it with schema, and set the properties ProductName, ProductCode, ProductVersion, and Manufacturer.

  模式必须是包含`tables`和`_Validation_records`属性的模块对象；通常，应使用`msilib.schema`。

  此函数返回时，数据库将仅包含模式和验证记录。

`msilib.``add_data`(database, table, records)

  将所有记录添加到数据库中名为表的表。

  表参数必须是MSI模式中的预定义表之一，例如。`'Feature'`, `'File'`, `'Component'`, `'Dialog'`, `'Control'`, etc.

  记录应该是元组的列表，每个元组包含根据表的模式的记录的所有字段。对于可选字段，可以传递`None`。

  字段值可以是二进制类的int，字符串或实例。

class `msilib.``Binary`(filename)

  表示二进制表中的条目；使用`add_data()`插入此类对象会将名为filename的文件读入表中。

`msilib.``add_tables`(database, module)

  将模块中的所有表内容添加到数据库。模块必须包含属性tables，其中列出了应添加内容的所有表，以及每个具有实际内容的表的一个属性。

  这通常用于安装序列表。

`msilib.``add_stream`(database, name, path)

  将路径添加到数据库的`_Stream`表中，流名称为name。

`msilib.``gen_uuid`()

  以MSI通常需要的格式返回新的UUID。在大括号中，并且所有十六进制在大写）。

也可以看看

FCICreateFile UuidCreate UuidToString

## 34.1.1. Database Objects

`Database.``OpenView`(sql)

  通过调用`MSIDatabaseOpenView()`返回视图对象。sql是要执行的SQL语句。

`Database.``Commit`()

  通过调用`MSIDatabaseCommit()`来提交当前事务中待完成的更改。

`Database.``GetSummaryInformation`(count)

  通过调用`MsiGetSummaryInformation()`返回新的摘要信息对象。count是更新值的最大数量。

也可以看看

MSIDatabaseOpenView MSIDatabaseCommit MSIGetSummaryInformation

## 34.1.2. View Objects

`View.``Execute`(params)

  通过`MSIViewExecute()`执行视图的SQL查询。如果params不是`None`，则它是描述查询中参数标记的实际值的记录。

`View.``GetColumnInfo`(kind)

  通过调用`MsiViewGetColumnInfo()`返回描述视图列的记录。种类可以是`MSICOLINFO_NAMES`或`MSICOLINFO_TYPES`。

`View.``Fetch`()

  通过调用`MsiViewFetch()`返回查询的结果记录。

`View.``Modify`(kind, data)

  通过调用`MsiViewModify()`修改视图。kind can be one of `MSIMODIFY_SEEK`, `MSIMODIFY_REFRESH`, `MSIMODIFY_INSERT`, `MSIMODIFY_UPDATE`, `MSIMODIFY_ASSIGN`, `MSIMODIFY_REPLACE`, `MSIMODIFY_MERGE`, `MSIMODIFY_DELETE`, `MSIMODIFY_INSERT_TEMPORARY`, `MSIMODIFY_VALIDATE`, `MSIMODIFY_VALIDATE_NEW`, `MSIMODIFY_VALIDATE_FIELD`, or `MSIMODIFY_VALIDATE_DELETE`.

  数据必须是描述新数据的记录。

`View.``Close`()

  通过`MsiViewClose()`关闭视图。

也可以看看

MsiViewExecute MSIViewGetColumnInfo MsiViewFetch MsiViewModify MsiViewClose

## 34.1.3. Summary Information Objects

`SummaryInformation.``GetProperty`(field)

  通过`MsiSummaryInfoGetProperty()`返回摘要的属性。field is the name of the property, and can be one of the constants `PID_CODEPAGE`, `PID_TITLE`, `PID_SUBJECT`, `PID_AUTHOR`, `PID_KEYWORDS`, `PID_COMMENTS`, `PID_TEMPLATE`, `PID_LASTAUTHOR`, `PID_REVNUMBER`, `PID_LASTPRINTED`, `PID_CREATE_DTM`, `PID_LASTSAVE_DTM`, `PID_PAGECOUNT`, `PID_WORDCOUNT`, `PID_CHARCOUNT`, `PID_APPNAME`, or `PID_SECURITY`.

`SummaryInformation.``GetPropertyCount`()

  通过`MsiSummaryInfoGetPropertyCount()`返回摘要属性的数量。

`SummaryInformation.``SetProperty`(field, value)

  通过`MsiSummaryInfoSetProperty()`设置属性。字段可以具有与`GetProperty()`中相同的值，value是属性的新值。可能的值类型是整数和字符串。

`SummaryInformation.``Persist`()

  使用`MsiSummaryInfoPersist()`将修改后的属性写入摘要信息流。

也可以看看

MsiSummaryInfoGetProperty MsiSummaryInfoGetPropertyCount MsiSummaryInfoSetProperty MsiSummaryInfoPersist

## 34.1.4. Record Objects

`Record.``GetFieldCount`()

  通过`MsiRecordGetFieldCount()`返回记录的字段数。

`Record.``GetInteger`(field)

  在可能的情况下，将字段的值作为整数返回。字段必须为整数。

`Record.``GetString`(field)

  在可能的情况下，将字段的值作为字符串返回。字段必须为整数。

`Record.``SetString`(field, value)

  将字段设置为值到`MsiRecordSetString()`。字段必须为整数； 值字符串。

`Record.``SetStream`(field, value)

  通过`MsiRecordSetStream()`将字段设置为名为值的文件的内容。字段必须为整数； 值字符串。

`Record.``SetInteger`(field, value)

  将字段设置为值到`MsiRecordSetInteger()`。字段和值必须为整数。

`Record.``ClearData`()

  通过`MsiRecordClearData()`将记录的所有字段设置为0。

也可以看看

MsiRecordGetFieldCount MsiRecordSetString MsiRecordSetStream MsiRecordSetInteger MsiRecordClear

## 34.1.5. Errors

MSI函数周围的所有封装引发`MsiError`；字符串里面的异常将包含更多的细节。

## 34.1.6. CAB Objects

class `msilib.``CAB`(name)

  类`CAB`表示CAB文件。在MSI构建期间，文件将同时添加到`Files`表和CAB文件。然后，当添加了所有文件后，可以写入CAB文件，然后将其添加到MSI文件。

  name是MSI文件中的CAB文件的名称。

  `append`(full, file, logical)

    将路径名称为full的文件添加到CAB文件中，名称logical。如果已有一个名为logical的文件，则会创建一个新文件名。

    返回CAB文件中文件的索引，以及CAB文件中文件的新名称。

  `commit`(database)

    生成CAB文件，将其作为流添加到MSI文件，将其放入`Media`表中，并从磁盘中删除生成的文件。

## 34.1.7. Directory Objects

class `msilib.``Directory`(database, cab, basedir, physical, logical, default[, componentflags])

  在目录表中创建一个新目录。目录的每个时间点都有一个当前组件，它通过`start_component()`显式创建，或者在第一次添加文件时隐式创建。文件添加到当前组件中，并添加到cab文件中。要创建目录，需要指定基本目录对象（可以是`None`），物理目录的路径和逻辑目录名称。默认指定目录表中的DefaultDir插槽。componentflags指定新组件获取的默认标志。

  `start_component`(component=None, feature=None, flags=None, keyfile=None, uuid=None)

    向组件表中添加一个条目，并使此组件成为此目录的当前组件。如果没有给出组件名称，则使用目录名称。如果未给出特征，则使用当前特征。如果没有给出标志，则使用目录的默认标志。如果未给出密钥文件，则KeyPath在组件表中保留为空。

  `add_file`(file, src=None, version=None, language=None)

    将一个文件添加到目录的当前组件，如果没有当前组件，则启动一个新的组件。默认情况下，源和文件表中的文件名将是相同的。如果指定了src文件，则相对于当前目录进行解释。或者，可以为文件表中的条目指定版本和语言。

  `glob`(pattern, exclude=None)

    向glob模式中指定的当前组件添加文件列表。可以在排除列表中排除单个文件。

  `remove_pyc`()

    在卸载时删除`.pyc` / `.pyo`文件。

也可以看看

目录表 文件表 组件表 FeatureComponents表

## 34.1.8. Features

class `msilib.``Feature`(db, id, title, desc, display, level=1, parent=None, directory=None, attributes=0)

  Add a new record to the `Feature` table, using the values id, parent.id, title, desc, display, level, directory, and attributes. 生成的特征对象可以传递到`Directory`的`start_component()`方法。

  `set_current`()

    将此功能设为`msilib`的当前功能。新组件将自动添加到默认要素，除非显式指定要素。

也可以看看

功能表

## 34.1.9. GUI classes

`msilib`提供了几个将GUI表包装在MSI数据库中的类。然而，没有提供标准用户界面；使用`bdist_msi`创建具有用于安装Python软件包的用户界面的MSI文件。

class `msilib.``Control`(dlg, name)

  对话框控件的基类。dlg是控件所属的对话框对象，name是控件的名称。

  `event`(event, argument, condition=1, ordering=None)

    对此控件的`ControlEvent`表进行输入。

  `mapping`(event, attribute)

    在此控件的`EventMapping`表中输入内容。

  `condition`(action, condition)

    对此控件的`ControlCondition`表进行输入。

class `msilib.``RadioButtonGroup`(dlg, name, property)

  创建名为名称的单选按钮控件。属性是在选择单选按钮时设置的安装程序属性。

  `add`(name, x, y, width, height, text, value=None)

    向坐标x，y，宽度，添加名为名称的单选按钮height和标签text。如果值为`None`，则默认为名称。

class `msilib.``Dialog`(db, name, x, y, w, h, attr, title, first, default, cancel)

  返回一个新的`Dialog`对象。在`Dialog`表中创建一个条目，指定的坐标，对话框属性，标题，第一个，默认和取消控件的名称。

  `control`(name, type, x, y, width, height, attributes, property, text, control_next, help)

    返回新的`Control`对象。在`Control`表中的条目使用指定的参数。

    这是一个通用的方法；对于特定类型，提供专门的方法。

  `text`(name, x, y, width, height, attributes, text)

    添加并返回`Text`控件。

  `bitmap`(name, x, y, width, height, text)

    添加并返回`Bitmap`控件。

  `line`(name, x, y, width, height)

    添加并返回`Line`控件。

  `pushbutton`(name, x, y, width, height, attributes, text, next_control)

    添加并返回`PushButton`控件。

  `radiogroup`(name, x, y, width, height, attributes, property, text, next_control)

    添加并返回`RadioButtonGroup`控件。

  `checkbox`(name, x, y, width, height, attributes, property, text, next_control)

    添加并返回`CheckBox`控件。

也可以看看

对话框 控制表 控制类型 ControlCondition表 ControlEvent表 RadioButton表

## 34.1.10. Precomputed tables

`msilib`提供了几个仅包含模式和表定义的子包。目前，这些定义基于MSI 2.0版。

`msilib.``schema`

  这是MSI 2.0的标准MSI模式，其中表变量​​提供表定义列表，_Validation_records提供MSI验证数据。

`msilib.``sequence`

  此模块包含标准序列表的表内容：AdminExecuteSequence，AdminUISequence，AdvtExecuteSequence，InstallExecuteSequence和 InstallUISequence。

`msilib.``text`

  此模块包含标准安装程序操作的UIText和ActionText表的定义。