Packaging Python with Microsoft Installer

by Martin v. Löwis 1

Abstract
Python releases for Windows up to and including Python 2.3 are packaged with the Wise Installer. For Python 2.4, we have developed a packaging system based on Microsoft Installer.

Introduction

Installation of software on Microsoft Windows typically uses precompiled binaries; compilation of software from sources is uncommon. Furthermore, Windows users expect an automated (or half-automated) installation procedure which copies the files to the hard disk (giving the user a choice where to place the files), creates proper entries in the Windows registry, and creates relevant entries in the start menu. Some installation procedures are even more involved: they may have to locate pre-existing software, either to use it or to complain about conflicts, they may have to start a Windows NT service, or perform other post-installation activities (such as generating byte code files from Python source code). In addition, users also expect that software comes with a deinstallation routine that undoes all the changes that installation did.

The culture of software installation has significantly advanced over the last ten years: user interfaces to software installation have been streamlined, and installation procedures became more automatic. For the software developer, this means that creation of an installation routine is a sub-project on its own. Third-party software has been developed to simplify creation of installers, such as InstallShield, or Wise. These installer generation packages typically create a Win32 executable (these days - they used to create Win16 executables), which provides a user interface and incorporates the data files to install in the installer executable itself.

Starting with Office 2000, Microsoft has developed a different technology for installation routines. In this technology, Microsoft Installer, the actual installation engine becomes part of the operating system (systems which don't have Installer need to install Installer first). The data files and descriptions of the installation routine are stored in a relational database, which carries the extension .MSI (for Microsoft Installer).

Meanwhile, Microsoft Installer becomes pre-packaged with Windows releases such as Windows XP or Windows 2003. It offers a number of advantages over traditional installation engines. We have started to develop an Installer package for Python, which can be used to distribute Python 2.4 when this software is released.

In the coming sections, we present a rationale for switching from Wise, which is currently used to package Python, to Microsoft Installer. We then explain details of the technology chosen for creating Installer packages, followed by an outlook to further extensions of the Installer infrastructure of Python.

Avoid Proprietary Packagers

With the technology used for Python 2.3, creating installers for Windows is possible to only a few developers. To create an installer, one first has to compile Python from source code, and then package the resulting binaries. Compilation of Python is done using Microsoft Visual C, which is available to many users that actively develop software in C or C++ on Windows. On the other hand, packaging requires a copy of the Wise installer, which is not that widely available. Wise has generously offered a free copy to whoever performs the packaging, which means that single person needs to perform the packaging. Using proprietary packaging software in a free software project means that volunteers who want to take over packaging responsibility need to find somebody to sponsor a copy of the package, or need to invest money into buying a copy.

With Microsoft Installer, it becomes possible to create packages without a proprietary packaging tool. The installer engine itself is available free of charge from Microsoft, and it provides a programmatic interface to create installation packages. Many of the traditional packaging tools use these programmatic interfaces for convenient creation of installer packages (e.g. Wise for Installer, Visual Studio .NET, InstallShield DevStudio 9). However, it is not necessary to use one of these products to create installer packages.

Support Win64 Platforms

One problem with the Win32 installation executables is that they do not work well on the recently developed Windows ports for Itanium and AMD64 processors (collectively called Win64). While these systems support the execution of Win32 applications, the Win32 emulation layer performs file system and registry redirection, so that Win32 programs cannot write into the system32 folder (accesses to system32 are redirected to SysWOW64).

Microsoft Installer does support Win64, but requires certain specific settings in the installation database (the .MSI file) to operate properly on Win64. Unfortunately, few (if any) products that support MSI generation provide convenient generation of proper Win64 installer packages, so that one has to use the programmatic interface to package generation for Win64.

Non-Interactive Installation

At times, administrators want to perform unattended installation of software. During the installation, no user interface should be opened. The Wise installer provides the /s option for non-interactive installation, but configuration information cannot be provided during such an installation.

Microsoft Installer packages can be installed through msiexec. msiexec allows both to parameterize the installation process itself (e.g. choosing a repair installation, or an uninstallation), as well as to parameterize the package, if supported by the package. Package parameterization typically allows the setting of target directories, and the selection of features to install.

Installation through Group Policy

To install software on each computer of a Windows domain, the Microsoft server systems support a mechanism called "group policy". This mechanism allows assigning Installer packages to a group of computers or a group of users, which get installed the next time the user logs on, or the system is rebooted. The administrator can select the level of user interface (basic or full) that is presented during installation, and can assign additional parameterization of the package by means of so-called "transforms".

Implementation Strategy

As indicated above, Installer provides an API for programmatic creation of installation databases. This API is available both as a DLL through C level function calls, and through COM automation.

We have exposed the installer API to Python, taking the route of accessing the API through COM. Because of that choice, invoking the installer generation requires Mark Hammond's Win32 extensions for Python, available as a separate package or as part of ActivePython.

The installation routine consists of two Python modules: msilib.py and msi.py. The former is a library abstracting common tasks in MSI creation into classes and functions; the latter is the script that actually generates Python installer. In addition, two Python files (schema.py and sequence.py) describe the structure of an "empty" MSI package, according to the Microsoft documentation of the database schema and the standard installation actions sequence. Creating a new database gives a completely empty database (i.e. none of the standard tables present); installing the scheme and the action sequences binds the resulting package to a certain version of Installer 2.

In the process of generating the installer package, a CAB archive needs to be creating containing the actual files to be installed. To create this cabinet archive, the tool cabarc.exe is needed, which is available both with Microsoft Visual Studio, and with the platform SDK (which is available free of charge).

Current Status

The software to create installer packages has been committed to the sandbox/msi directory of the Python CVS. Sample installers (packaging the current Python CVS code) are available from http://www.dcl.hpi.uni-potsdam.de/home/loewis/installer.html. The package offers roughly the same user interface and functionality that the previous (Wise-based) installer offers.

Future Work

The library developed as part of the project can be used to create other installer packages through Python scripts. In particular, it would be possible to integrate it into distutils, offering a bdist_msi command as an alternative to bdist_wininst for Windows binary distutils packages.

Author Background

Dr. Martin v. Löwis is a regular contributor to the core Python project, and a director of the Python Software Foundation. He currently works at the Hasso-Plattner-Institut as a university teacher.

[1]Contact: Hasso-Plattner-Institut für Softwaresystemtechnik, PF 900460, 14440 Potsdam, Germany. Email: Martin.vonLoewis@hpi.uni-potsdam.de
[2]Currently, the resulting packages require Installer 2.0.