Specifying the Code Page for Patch Tables

Code pages describe a character set. In MSI Databases and Code Pages I described how Windows Installer databases use a code page for the string pool, as well that the summary information stream uses its own code page in PID_CODEPAGE (1) to describe strings in the summary information stream. There is a bug, however, when creating a .msp patch database from a .pcp patch creation database using PatchWiz.dll. The code page of the .pcp database is not set in the .msp patch, so non-ASCII character don’t show up correctly. You can verify this using the msiinfo.exe tool in the Windows Installer SDK by passing the path to the .msp file with extended characters, and the -b and -d command-line switches (in that order). This will show the code page of the database and show you the string pool. The code page for the .msp database itself is 0. The code page for the transforms in the patch are still correct, so your target database is transformed correctly.

This can still be a problem, however, since starting with Windows Installer 3.0, patches are displayed automatically in the Add/Remove Programs (ARP) control panel applet using the MsiPatchMetadata table in the .msp file itself. Since the characters aren’t displayed right and the code page is not set, the ARP entry for the patch may not appear correctly either.

To fix this you can either export the MsiPatchMetadata table to a text archive file and fix the strings, or have an archive file already prepared. Make sure it includes the code page as the first field in the third line, like in the following example:

Company Property    Value

S0  s0  S0

932 MsiPatchMetadata    Company Property

When you import the archive file it replaces the existing table and in this example sets the database code page to 932 for support of the Japanese character set. Be sure not to override a code page that has been set for the database already or characters in other tables may not display correctly. A database may have only a single code page since it uses a shared string pool.

You can import and export tables using Orca from the Tables menu, clicking either the Export Tables or the Import Tables menu. Programmatically you can use the MsiDatabaseExport and MsiDatabaseImport functions, or the Database.Export and Database.Import automation methods.