"msilib" --- Leer y escribir archivos *Microsoft Installer*
***********************************************************

**Código fuente:** Lib/msilib/__init__.py

======================================================================

El "msilib" soporta la creación de archivos *Microsoft Installer*
(".msi"). Como estos archivos a menudo contienen archivos *cabinet*
(".cab") embebidos, se expone también una API para crear archivos CAB.
El soporte para leer archivos ".cab" todavía no está implementado; el
soporte a lectura de base de datos ".msi" es posible.

Este paquete se centra en proveer acceso completo a todas las tablas
de un archivo ".msi", por lo que se puede considerar una API de bajo
nivel. Dos aplicaciones principales de este paquete son el comando
"bdist_msi" de "distutils", y la creación del propio paquete
instalador de Python (aunque utiliza una versión diferente de
"msilib").

El contenido del paquete se puede dividir en cuatro partes: rutinas
CAB de bajo nivel, rutinas MSI de bajo nivel, rutinas MSI de alto
nivel, y estructuras de tabla estándar.

msilib.FCICreate(cabname, files)

   Crea un nuevo archivo CAB llamado *cabname*. *files* debe ser una
   lista de tuplas, donde cada una contiene el nombre del archivo en
   disco, y el nombre del archivo dentro del archivo CAB.

   Los archivos son añadidos al archivo CAB en el orden en el cual
   aparecen en la lista. Todos los archivos son añadidos a un solo
   archivo CAB, utilizando el algoritmo de compresión MSZIP.

   Las retrollamadas a Python para los diferentes pasos de la creación
   de MSI no están actualmente expuestas.

msilib.UuidCreate()

   Retorna la representación de un nuevo identificador único como
   cadena de caracteres. Esto envuelve las funciones "UuidCreate()" y
   "UuidToString()" de la API de Windows.

msilib.OpenDatabase(path, persist)

   Retorna una nueva base de datos llamando a MsiOpenDatabase. *path*
   es el nombre del archivo MSI; *persist* puede ser una de las
   constantes "MSIDBOPEN_CREATEDIRECT", "MSIDBOPEN_CREATE",
   "MSIDBOPEN_DIRECT", "MSIDBOPEN_READONLY" o "MSIDBOPEN_TRANSACT", y
   puede incluir la bandera "MSIDBOPEN_PATCHFILE". El significado de
   estas banderas se puede consultar en la documentación de Microsoft;
   dependiendo de las banderas, se abrirá una base de datos existente,
   o se creará una nueva.

msilib.CreateRecord(count)

   Retorna un nuevo objeto de registro llamando a "MSICreateRecord()".
   *count* es el número de campos del registro.

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

   Crea y retorna una nueva base de datos *name*, la inicializa con
   *schema*, y establece las propiedades *ProductName*, *ProductCode*,
   *ProductVersion* y *Manufacturer*.

   *schema* debe ser un objeto módulo que contenga los atributos
   "tables" y "_Validation_records"; normalmente se debería usar
   "msilib.schema".

   La base de datos contendrá únicamente el esquema y los registros de
   validación cuando esta función retorne.

msilib.add_data(database, table, records)

   Añade todos los *records* de la tabla llamada *table* a *database*.

   El argumento *table* debe ser una de las tablas predefinidas en el
   esquema MSI, como "'Feature'", "'File'", "'Component'", "'Dialog'",
   "'Control'", etc.

   *records* debería ser una lista de tuplas, donde cada una contenga
   todos los campos de un registro, acorde al esquema de la tabla.
   Para los campos opcionales se puede asignar "None".

   Los valores de los campos pueden ser enteros, cadenas de caracteres
   o instancias de la clase Binary.

class msilib.Binary(filename)

   Representa entradas en la tabla Binary; insertar un objeto así
   utilizando "add_data()" lee el archivo llamado **filename** en la
   tabla.

msilib.add_tables(database, module)

   Añade todos los contenidos de la tabla de *module* a *database*.
   *module* debe contener un atributo *tables*, que liste todas las
   tablas cuyos contenidos deban ser añadidos, y un atributo por tabla
   que contenga el propio contenido.

   Esto suele utilizarse para instalar las tablas secuenciales.

msilib.add_stream(database, name, path)

   Añade el archivo *path* en la tabla "_Stream" de *database*, con el
   nombre del flujo *name*.

msilib.gen_uuid()

   Retorna un nuevo UUID, en el formato que MSI suele requerir (entre
   llaves, con todos los dígitos hexadecimales en mayúsculas).

Ver también: FCICreate UuidCreate UuidToString


Objetos Database
================

Database.OpenView(sql)

   Retorna un objeto de vista, llamando a "MSIDatabaseOpenView()".
   *sql* es la sentencia SQL a ejecutar.

Database.Commit()

   Persiste (**commit**) los cambios pendientes en la transacción
   actual, llamando a "MSIDatabaseCommit()".

Database.GetSummaryInformation(count)

   Retorna un nuevo objeto de información resumida, llamando a
   "MsiGetSummaryInformation()". *count* es el número máximo de
   valores actualizados.

Database.Close()

   Cierra el objeto de base de datos, mediante "MsiCloseHandle()".

   Nuevo en la versión 3.7.

Ver también:

  MSIDatabaseOpenView MSIDatabaseCommit MSIGetSummaryInformation
  MsiCloseHandle


Objetos View
============

View.Execute(params)

   Ejecuta la consulta SQL de la vista, mediante "MSIViewExecute()".
   Si *params* no es "None", es un registro que describe los valores
   actuales de los *tokens* del parámetro en la consulta.

View.GetColumnInfo(kind)

   Retorna un registro que describe las columnas de la vista, llamando
   a "MsiViewGetColumnInfo()". *kind* puede ser "MSICOLINFO_NAMES" o
   "MSICOLINFO_TYPES".

View.Fetch()

   Retorna un registro de resultado de la consulta, llamando a
   "MsiViewFetch()".

View.Modify(kind, data)

   Modifica la vista, llamando a "MsiViewModify()". *kind* puede ser
   "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" o
   "MSIMODIFY_VALIDATE_DELETE".

   *data* debe ser un registro que describa los nuevos datos.

View.Close()

   Cierra la vista, mediante "MsiViewClose()".

Ver también:

  MsiViewExecute MSIViewGetColumnInfo MsiViewFetch MsiViewModify
  MsiViewClose


Objetos Summary Information
===========================

SummaryInformation.GetProperty(field)

   Retorna una propiedad del resumen, mediante
   "MsiSummaryInfoGetProperty()". *field* es el nombre de la
   propiedad, y puede ser una de las constantes: "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" o
   "PID_SECURITY".

SummaryInformation.GetPropertyCount()

   Retorna el número de propiedades del resumen, mediante
   "MsiSummaryInfoGetPropertyCount()".

SummaryInformation.SetProperty(field, value)

   Establece una propiedad mediante "MsiSummaryInfoSetProperty()".
   *field* puede tener los mismos valores que en "GetProperty()";
   *value* es el nuevo valor de la propiedad. Los tipos de los valores
   pueden ser enteros o cadenas de caracteres.

SummaryInformation.Persist()

   Escribe las propiedades modificadas al flujo de información
   resumida, mediante "MsiSummaryInfoPersist()".

Ver también:

  MsiSummaryInfoGetProperty MsiSummaryInfoGetPropertyCount
  MsiSummaryInfoSetProperty MsiSummaryInfoPersist


Objetos Record
==============

Record.GetFieldCount()

   Retorna el número de campos del registro, mediante
   "MsiRecordGetFieldCount()".

Record.GetInteger(field)

   Retorna el valor de *field* como entero cuando sea posible. *field*
   debe ser un entero.

Record.GetString(field)

   Retorna el valor de *field* como una cadena de caracteres cuando
   sea posible. *field* debe ser un entero.

Record.SetString(field, value)

   Establece *field* a *value* mediante "MsiRecordSetString()".
   *field* debe ser un entero; *value* una cadena de caracteres.

Record.SetStream(field, value)

   Establece *field* al contenido del archivo llamado *value*,
   mediante "MsiRecordSetStream()". *field* debe ser un entero;
   *value* una cadena de caracteres.

Record.SetInteger(field, value)

   Establece *field* a *value* mediante "MsiRecordSetInteger()".
   *field* y *value* deben ser enteros.

Record.ClearData()

   Establece todos los campos del registro a 0, mediante
   "MsiRecordClearData()".

Ver también:

  MsiRecordGetFieldCount MsiRecordSetString MsiRecordSetStream
  MsiRecordSetInteger MsiRecordClearData


Errores
=======

Todos los *wrappers* sobre funciones MSI lanzan "MSIError"; la cadena
de caracteres dentro de la excepción contendrá más detalles.


Objetos CAB
===========

class msilib.CAB(name)

   La clase "CAB" representa un archivo CAB. Durante la construcción
   del MSI, los archivos se añadirán simultáneamente a la table
   "Files", y a un archivo CAB. Después, cuando todos los archivos
   sean añadidos, el archivo CAB puede ser sobreescrito, y finalmente
   añadido al archivo MSI.

   *name* es el nombre del archivo CAB dentro del archivo MSI.

   append(full, file, logical)

      Añade el archivo con la ruta *full* al archivo CAB, bajo el
      nombre *logical*. Si ya existe algún archivo llamado *logical*,
      se creará un nuevo archivo.

      Retorna el índice del archivo dentro del archivo CAB, y el nuevo
      nombre del archivo dentro del archivo CAB.

   commit(database)

      Genera un archivo CAB, lo añade como un flujo al archivo MSI, lo
      añade a la tabla "Media", y elimina el archivo generado del
      disco.


Objetos Directory
=================

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

   Crea un nuevo directorio en la tabla *Directory*. Hay un componente
   actual en cada punto temporal para el directorio, el cual es, o
   bien explícitamente creado mediante "start_component()", o bien
   implícito cuando los archivos se añaden por primera vez. Los
   archivos son añadidos en el componente actual, y al archivo CAB.
   Para crear un directorio, un objeto de directorio base tiene que
   ser especificado (puede ser "None"), la ruta al directorio físico,
   y un nombre de directorio lógico. *default* especifica el zócalo
   *DefaultDir* en la table de directorio. *componentflags* especifica
   las banderas por defecto que obtendrán los nuevos componentes.

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

      Añade una entrada a la tabla *Component*, y hace este componente
      el actual componente para este directorio. Si no se especifica
      ningún nombre de componente, se usará el nombre del directorio.
      Si no se especifica ninguna *feature*, se usará la
      característica actual. Si no se especifican *flags*, se usarán
      las banderas por defecto del directorio. Si no se especifica
      ningún *keyfile*, el *KeyPath* quedará nulo en la tabla
      *Component*.

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

      Añade el archivo al componente actual del directorio,
      inicializando uno nuevo si no existe un componente actual. Por
      defecto, el nombre del archivo en el origen y la tabla del
      archivo serán idénticos. Si se especifica el archivo *src*, se
      interpretará como relativo al directorio actual. Opcionalmente,
      se pueden especificar una *version* y un *language* para la
      entrada en la tabla *File*.

   glob(pattern, exclude=None)

      Añade una lista de archivos al componente actual, como se
      especifica en el patrón *glob*. Se pueden excluir archivos
      individualmente en la lista *exclude*.

   remove_pyc()

      Elimina los archivos ".pyc" al desinstalar.

Ver también:

  Directory Table File Table Component Table FeatureComponents Table


Features
========

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

   Añade un nuevo registro a la tabla "Feature", usando los valores
   *id*, *parent.id*, *title*, *desc*, *display*, *level*, *directory*
   y *attributes*. El objeto de característica resultante se le puede
   dar al método "start_component()" de "Directory".

   set_current()

      Establece esta característica como la actual característica de
      "msilib". Los nuevos componentes serán añadidos automáticamente
      a la característica por defecto, a no ser que se especifique
      explícitamente una característica.

Ver también: Feature Table


Clases GUI
==========

"msilib" dispone de varias clases que envuelven a las tablas GUI en
una base de datos MSI. Sin embargo, no se dispone de ninguna interfaz
de usuario estándar; se puede usar "bdist_msi" para crear archivos MSI
con una interfaz de usuario para instalar paquetes Python.

class msilib.Control(dlg, name)

   Clase base de los controles de diálogo. *dlg* es el objeto de
   diálogo al que pertenece el control, y *name* es el nombre del
   control.

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

      Crea una entrada en la tabla "ControlEvent" para este control.

   mapping(event, attribute)

      Crea una entrada en la tabla "EventMapping" para este control.

   condition(action, condition)

      Crea una entrada en la tabla "ControlCondition" para este
      control.

class msilib.RadioButtonGroup(dlg, name, property)

   Crea un control de botón de selección llamado *name*. *property* es
   la propiedad del instalador que se establece cuando un botón de
   selección es seleccionado.

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

      Añade un botón de selección llamado *name* al grupo, en las
      coordenadas *x*, *y*, *width*, *height*, con la etiqueta *text*.
      Si *value* es "None", se establecerá por defecto a *name*.

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

   Retorna un nuevo objeto "Dialog". Se creará una entrada en la tabla
   "Dialog" con las coordenadas, atributos de diálogo y título
   especificados, así como los nombres del primer control y los
   controles por defecto y de cancelación.

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

      Retorna un nuevo objeto "Control". Se creará una entrada en la
      tabla "Control" con los parámetros especificados.

      Este es un método genérico; para tipos específicos hay métodos
      especializados disponibles.

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

      Añade y retorna un control "Text".

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

      Añade y retorna un control "Bitmap".

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

      Añade y retorna un control "Line".

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

      Añade y retorna un control "PushButton".

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

      Añade y retorna un control "RadioButtonGroup".

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

      Añade y retorna un control "CheckBox".

Ver también:

  Dialog Table Control Table Control Types ControlCondition Table
  ControlEvent Table EventMapping Table RadioButton Table


Tablas pre-calculadas
=====================

"msilib" proporciona algunos subpaquetes que contienen únicamente
definiciones de esquema y tabla. Actualmente, estas definiciones están
basadas en la versión 2.0 de MSI.

msilib.schema

   Este es el esquema estándar MSI para MSI 2.0, con la variable
   *tables* proporcionando una lista de definición de tablas, y
   *_Validation_records* proporcionando la información para la
   validación MSI.

msilib.sequence

   Este módulo alberga los contenidos de la tabla para las tablas de
   secuencia estándar: *AdminExecuteSequence*, *AdminUISequence*,
   *AdvtExecuteSequence*, *InstallExecuteSequence*, and
   *InstallUISequence*.

msilib.text

   Este módulo contiene definiciones para las tablas *UIText* y
   *ActionText*, para las acciones estándar del instalador.
