"msilib" --- Microsoft インストーラーファイルの読み書き
*******************************************************

**ソースコード:** Lib/msilib/__init__.py

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

"msilib" モジュールは Microsoft インストーラー(".msi")の作成を支援しま
す。このファイルは大抵の場合埋め込まれた「キャビネット」ファイル
(".cab") を含むので、CAB ファイル作成用の API も公開されています。
".cab" ファイルの読み出しは現時点では実装されていませんが、 ".msi" デ
ータベースの読み出しは可能です。

このパッケージの目的は ".msi" ファイルにある全てのテーブルへの完全なア
クセスの提供であり、提供されているものは非常に低レベルな API です。こ
のパッケージの二つの主要な使用目的は "distutils" の "bdist_msi" コマン
ドと、Python インストーラーパッケージそれ自体(と言いつつ現在は別バージ
ョンの "msilib" を使っているのですが)です。

パッケージの内容は大きく四つのパートに分けられます。低レベル CAB ルー
チン、低レベル MSI ルーチン、少し高レベルの MSI ルーチン、標準的なテー
ブル構造、の四つです。

msilib.FCICreate(cabname, files)

   新しい CAB ファイルを *cabname* という名前で作ります。*files* はタ
   プルのリストで、それぞれのタプルはディスク上のファイル名と CAB ファ
   イルで付けられるファイル名で構成されなければなりません。

   ファイルはリストに現れた順番で CAB ファイルに追加されます。全てのフ
   ァイルは MSZIP 圧縮アルゴリズムを使って一つの CAB ファイルに追加さ
   れます。

   MSI 作成の様々なステップに対する Python コールバックは現在公開され
   ていません。

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)

   *name* という名前の新しいデータベースを作り、*schema* で初期化し、
   プロパティ *ProductName*, *ProductCode*, *ProductVersion*,
   *Manufacturer* をセットして、返します。

   *schema* は "tables" と "_Validation_records" という属性をもったモ
   ジュールオブジェクトでなければなりません。大抵の場合、
   "msilib.schema" を使うべきです。

   データベースはこの関数から返された時点でスキーマとバリデーションレ
   コードだけが収められています。

msilib.add_data(database, table, records)

   全ての *records* を *database* の *table* テーブルに追加します。

   *table* 引数は MSI スキーマで事前に定義されたテーブルでなければなり
   ません。例えば、"'Feature'", "'File'", "'Component'", "'Dialog'",
   "'Control'", などです。

   *records* はタプルのリストで、それぞれのタプルにはテーブルのスキー
   マに従ったレコードの全てのフィールドを含んでいるものでなければなり
   ません。オプションのフィールドには "None" を渡すことができます。

   フィールドの値には、整数・文字列・Binary クラスのインスタンスが使え
   ます。

class msilib.Binary(filename)

   Binary テーブル中のエントリーを表わします。 "add_data()" を使ってこ
   のクラスのオブジェクトを挿入するときには *filename* という名前のフ
   ァイルをテーブルに読み込みます。

msilib.add_tables(database, module)

   *module* の全てのテーブルの内容を *database* に追加します。*module*
   は *tables* という内容が追加されるべき全てのテーブルのリストと、テ
   ーブルごとに一つある実際の内容を持っている属性とを含んでいなければ
   なりません。

   この関数は典型的にシーケンステーブルをインストールするために使われ
   ます。

msilib.add_stream(database, name, path)

   *database* の "_Stream" テーブルに、ファイル *path* を *name* とい
   うストリーム名で追加します。

msilib.gen_uuid()

   新しい UUID を、MSI が通常要求する形式(つまり、中括弧で囲み、16進数
   は大文字)で返します。

参考: FCICreate UuidCreate UuidToString


データベースオブジェクト
========================

Database.OpenView(sql)

   "MSIDatabaseOpenView()" を呼び出して取得したビューオブジェクトを返
   します。 *sql* は実行される SQL ステートメントです。

Database.Commit()

   "MSIDatabaseCommit()" を呼び出して現在のトランザクションで保留され
   ている変更をコミットします。

Database.GetSummaryInformation(count)

   "MsiGetSummaryInformation()" を呼び出して新しいサマリー情報オブジェ
   クトを返します。 *count* は更新された値の最大数です。

Database.Close()

   "MsiCloseHandle()" を通してデータベースオブジェクトを閉じます。

   バージョン 3.7 で追加.

参考:

  MSIDatabaseOpenView MSIDatabaseCommit MSIGetSummaryInformation
  MsiCloseHandle


ビューオブジェクト
==================

View.Execute(params)

   "MSIViewExecute()" を通してビューに対する SQL 問い合わせを実行しま
   す。 *params* が "None" でない場合、クエリ中のパラメータトークンの
   実際の値を与えるものです。

View.GetColumnInfo(kind)

   "MsiViewGetColumnInfo()" の呼び出しを通してビューのカラムを説明する
   レコードを返します。 *kind* は "MSICOLINFO_NAMES" または
   "MSICOLINFO_TYPES" です。

View.Fetch()

   "MsiViewFetch()" の呼び出しを通してクエリの結果レコードを返します。

View.Modify(kind, data)

   "MsiViewModify()" を呼び出してビューを変更します。 *kind* は
   "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",
   "MSIMODIFY_VALIDATE_DELETE" のいずれかです。

   *data* は新しいデータを表わすレコードでなければなりません。

View.Close()

   "MsiViewClose()" を通してビューを閉じます。

参考:

  MsiViewExecute MSIViewGetColumnInfo MsiViewFetch MsiViewModify
  MsiViewClose


サマリー情報オブジェクト
========================

SummaryInformation.GetProperty(field)

   "MsiSummaryInfoGetProperty()" を通してサマリーのプロパティを返しま
   す。 *field* はプロパティ名で、定数 "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",
   "PID_SECURITY" のいずれかです。

SummaryInformation.GetPropertyCount()

   "MsiSummaryInfoGetPropertyCount()" を通してサマリープロパティの個数
   を返します。

SummaryInformation.SetProperty(field, value)

   "MsiSummaryInfoSetProperty()" を通してプロパティをセットします。
   *field* は "GetProperty()" におけるものと同じ値をとります。 *value*
   はプロパティの新しい値です。許される値の型は整数と文字列です。

SummaryInformation.Persist()

   "MsiSummaryInfoPersist()" を使って変更されたプロパティをサマリー情
   報ストリームに書き込みます。

参考:

  MsiSummaryInfoGetProperty MsiSummaryInfoGetPropertyCount
  MsiSummaryInfoSetProperty MsiSummaryInfoPersist


レコードオブジェクト
====================

Record.GetFieldCount()

   "MsiRecordGetFieldCount()" を通してレコードのフィールド数を返します
   。

Record.GetInteger(field)

   *field* の値を可能なら整数として返します。*field* は整数でなければ
   なりません。

Record.GetString(field)

   *field* の値を可能なら文字列として返します。*field* は整数でなけれ
   ばなりません。

Record.SetString(field, value)

   "MsiRecordSetString()" を通して *field* を *value* にセットします。
   *field* は整数、 *value* は文字列でなければなりません。

Record.SetStream(field, value)

   "MsiRecordSetStream()" を通して *field* を *value* という名のファイ
   ルの内容にセットします。 *field* は整数、 *value* は文字列でなけれ
   ばなりません。

Record.SetInteger(field, value)

   "MsiRecordSetInteger()" を通して *field* を *value* にセットします
   。 *field* も *value* も整数でなければなりません。

Record.ClearData()

   "MsiRecordClearData()" を通してレコードの全てのフィールドを 0 にセ
   ットします。

参考:

  MsiRecordGetFieldCount MsiRecordSetString MsiRecordSetStream
  MsiRecordSetInteger MsiRecordClearData


エラー
======

全ての MSI 関数のラッパーは "MSIError" を送出します。例外の内部の文字
列がより詳細な情報を含んでいます。


CAB オブジェクト
================

class msilib.CAB(name)

   "CAB" クラスは CAB ファイルを表わすものです。MSI 構築中、ファイルは
   "Files" テーブルと CAB ファイルとに同時に追加されます。そして、全て
   のファイルを追加し終えたら、CAB ファイルは書き込まれることが可能に
   なり、MSI ファイルに追加されます。

   *name* は MSI ファイル中の CAB ファイルの名前です。

   append(full, file, logical)

      パス名 *full* のファイルを CAB ファイルに *logical* という名で追
      加します。*logical* という名が既に存在したならば、新しいファイル
      名が作られます。

      ファイルの CAB ファイル中のインデクスと新しいファイル名を返しま
      す。

   commit(database)

      CAB ファイルを作り、MSI ファイルにストリームとして追加し、
      "Media" テーブルに送り込み、作ったファイルはディスクから削除しま
      す。


ディレクトリオブジェクト
========================

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

   新しいディレクトリを Directory テーブルに作成します。ディレクトリに
   は各時点で現在のコンポーネントがあります。そのコンポーネントは
   "start_component()" を使って明示的に作成されたか、最初にファイルが
   追加された際に暗黙裡に作成されたものです。ファイルは現在のコンポー
   ネントと cab ファイルの両方に追加されます。ディレクトリを作成するに
   は親ディレクトリオブジェクト("None" でも可)、物理的ディレクトリへの
   パス、論理的ディレクトリ名を指定する必要があります。 *default* はデ
   ィレクトリテーブルの DefaultDir スロットを指定します。
   *componentflags* は新しいコンポーネントが得るデフォルトのフラグを指
   定します。

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

      エントリを Component テーブルに追加し、このコンポーネントをこの
      ディレクトリの現在のコンポーネントにします。もしコンポーネント名
      が与えられなければディレクトリ名が使われます。*feature* が与えら
      れなければ、ディレクトリのデフォルトフラグが使われます。
      *keyfile* が与えられなければ、Component テーブルの KeyPath は
      null のままになります。

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

      ファイルをディレクトリの現在のコンポーネントに追加します。現在の
      コンポーネントが存在しない場合、新しいコンポーネントを開始します
      。デフォルトではソースとファイルテーブルのファイル名は同じになり
      ます。*src* ファイルが指定された場合、それは現在のディレクトリか
      ら相対的に解釈されます。オプションで *version* と *language* を
      File テーブルのエントリ用に指定することができます。

   glob(pattern, exclude=None)

      現在のコンポーネントに glob パターンで指定されたファイルのリスト
      を追加します。個々のファイルを *exclude* リストで除外することが
      できます。

   remove_pyc()

      アンインストールの際に ".pyc" を削除します。

参考: Directory Table File Table Component Table FeatureComponents Table


フィーチャー
============

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

   *id*, *parent.id*, *title*, *desc*, *display*, *level*,
   *directory*, *attributes* の値を使って、新しいレコードを "Feature"
   テーブルに追加します。出来上がったフィーチャーオブジェクトは
   "Directory" の "start_component()" メソッドに渡すことができます。

   set_current()

      このフィーチャーを "msilib" の現在のフィーチャーにします。フィー
      チャーを明示的に指定しない場合、新しいコンポーネントが自動的にデ
      フォルトのフィーチャーに追加されます。

参考: Feature Table


GUI クラス
==========

"msilib" はMSIデータベースにあるGUIテーブルをラップしたいくつかのクラ
スを提供します。しかし、標準的なユーザーインタフェースは提供されません
。ユーザーインタフェースを備えたPythonパッケージをインストールするMSI
を作成するには "bdist_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)

   *name* という名前のラジオボタンコントロールを作成します。*property*
   はラジオボタンが選ばれたときにセットされるインストーラープロパティ
   です。

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

      グループに *name* という名前で、座標 *x*, *y* に大きさが
      *width*, *height* で *text* というラベルの付いたラジオボタンを追
      加します。*value* が "None" なら、デフォルトは *name* になります
      。

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

   新しい "Dialog" オブジェクトを返します。 "Dialog" テーブルを以下の
   引数に渡された情報を元に作成します: 座標、ダイアログ属性、タイトル
   、first・default・cancelという三つのコントロールに対する名前。

   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" コントロールを追加して返します。

参考:

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


事前に計算されたテーブル
========================

"msilib" はスキーマとテーブル定義だけから成るサブパッケージをいくつか
提供しています。現在のところ、これらの定義は MSI バージョン 2.0 に基づ
いています。

msilib.schema

   これは MSI 2.0 用の標準 MSI スキーマで、テーブル定義のリストを提供
   する *tables* 変数と、MSI バリデーション用のデータを提供する
   *_Validation_records* 変数があります。

msilib.sequence

   このモジュールは標準シーケンステーブルのテーブル内容を含んでいます
   。*AdminExecuteSequence*, *AdminUISequence*, *AdvtExecuteSequence*,
   *InstallExecuteSequence*, *InstallUISequence* が含まれています。

msilib.text

   このモジュールは標準的なインストーラーのアクションのための UIText
   および ActionText テーブルの定義を含んでいます。
