List Tables in an Msi File

List Tables in an msi file?

MSI SDK: The _Tables table is a read-only system table that lists all the
tables in the database. Query this table to find out if a table
exists.

Adapting the script WiExport.vbs from the Windows Installer Scripting Examples from the Windows Installer SDK you get something like the below.



MSI SDK VBScripts: In order to find WiExport.vbs: With Visual Studio installed, look under: %ProgramFiles(x86)%\Windows Kits\10\bin\10.0.17763.0\x86 (adjust
version numbers for your current installation) (or just search for it on github.com).


Sample Screen Shot: Here is a sample run of the script below:

Sample Image

Sample: Procedure for script:

  • 1) save as ListMSITables.vbs on desktop (link to github.com)
  • 2) drag-and-drop an MSI file onto the VBScript
  • 3) a message box will show number of tables, and table names

Note: Very large MSI files could make the message box overflow the screen. Just press any key to dismiss (I use ESC).

On Error Resume Next
Const msiOpenDatabaseModeReadOnly = 0

Dim installer : Set installer = Nothing
Set installer = Wscript.CreateObject("WindowsInstaller.Installer")
Dim counter : counter = 0

' Verify incoming drag and drop arguments
If WScript.Arguments.Count = 0 Then MsgBox "Drag and drop an MSI file onto the VBScript" End If
filename = Wscript.Arguments(0)
If (Right (LCase(filename),3) <> "msi") Then
WScript.Quit
End If

Dim database : Set database = installer.OpenDatabase(filename, msiOpenDatabaseModeReadOnly)
Dim table, view, record

Set view = database.OpenView("SELECT `Name` FROM _Tables")
view.Execute

Do
Set record = view.Fetch
If record Is Nothing Then Exit Do
table = record.StringData(1)
tables = tables + table + vbNewLine
counter = counter + 1
Loop

MsgBox "Number of tables: " + CStr(counter) + vbNewLine + vbNewLine + tables

Set view = Nothing

Github.com: The above is obviously VBScript. Just pillage github.com for more
of the same, in all kinds of languages.


Links:

  • Post-Process MSI using MSI SDK VBScript WiRunSQL.vbs

Where can i find msi table column properties?

MSI SDK: This section in the MSI SDK lists the built-in MSI tables: https://learn.microsoft.com/en-us/windows/win32/msi/database-tables - see the Orca section below for more technical information: the file "orca.dat" in the Orca installation folder holds the schema.

Technicalities: A few things first: The tables starting with underscore: _ such as _Validation and _Streams are special tables - most of which are not visible from within Orca.

  • The _Validation table is a system table that essentially shows the database schema. It is used during MSI database validation (recommended read). You can see the different: Database Column Data Types.

    • Validation runs a series of checks on the MSI database and its content to check for common problems as well as consistency with the database schema.
    • The database checks are implemented in *.CUB files. They can contain runnable code against the database - for example VBScript files. Open the *.CUB files with Orca to see the content.
    • Validation can be invoked interactively from Orca or via the command line.
  • The _Streams table is a temporary table which is involved with SQL statements. Same thing with _Storages. And there are a few more such system tables.

Orca: Orca is the SDK tool for viewing and modifying MSI database files.

  • You can use Orca to open an MSI and select Tables => Export Tables... Specify an output directory and select to export all tables. You get *.idt files with description of the content. Open in Notepad or any text editor.

  • In the Orca installation folder there is a file called "orca.dat". This is apparently the database schema for MSI files. You can use the "Export Tables" approach for this file after you open it in Orca. Just export all tables and this should be all valid MSI tables exported to *.idt format. There will be headers which should indicate the datatypes:

    IDT Files

MSI SDK VBScript: Included in the SDK installed with Visual Studio you will find a number of VBScript files that show a number of techniques you can use when dealing with MSI files. The Windows Installer Scripting Examples. Look under: %ProgramFiles(x86)%\Windows Kits\10\bin\10.0.17134.0\x86 - replace with the current numbers for the penultimate folder name. Quick preview of the files here.

How to extract data (file count) from MSI File Table

Create a new visual studio project, add a reference to c:\windows\system32\msi.dll and use the following code to read the number of files in a msi file:

Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
var installer =
(WindowsInstaller.Installer)Activator.CreateInstance(installerType);
var msi = installer.OpenDatabase(@"path\to\some\file.msi", 0);
var fileView = msi.OpenView("SELECT FileName FROM File");
fileView.Execute(null);
int fileCount = 0;
while (fileView.Fetch() != null)
{
fileCount++;
}
Console.WriteLine(fileCount);

This code uses the WindowsInstaller.Installer COM object, which is the entry-point for the windows installer automation API. Take a look at the complete reference documentation.

edit: apparently wix comes with managed assemblies (in C:\program files\Windows Installer XML v3\sdk) which wrap msi.dll. I guess this is what Rob is referring to by "DTF" in his answer. Using the types in the Microsoft.Deployment.WindowsInstaller assembly and namespace would simplify the code sample to this:

var database = new Database(@"\path\to\some\file.msi");
var list = database.ExecuteQuery("SELECT FileName FROM File");
Console.WriteLine(list.Count);

How extract deployment files from MSI database

Phil has given you the easy/simple answer but I thought I might give you a little more information since you've done some research. Checkout:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa372919(v=vs.85).aspx

This is where the structured storage is. You'll see something like Disk1.cab as the Name (PK) and binary data. The data is a CAB file with the file entry in the cab matching the File.File column. From there you can use the File.FileName column to get the short name and long name (you'll want the long name no doubt) and do a joint to the Component table to get the directory table ID.

You'll also need to recurse the directory table to build the tree of directories and know where to put the files.

Fun stuff. There's some libraries in C# that make this WAY simpler. Or just call msiexec /a as Phil says. :)

How to read .mst(transform) Table along with .msi

An MST is by definition a transform. It only contains the deltas of a base MSI.

The database class has a method called ViewTransform. If the MST is compatible with the MSI it'll succeed and the changes appear in the _TransformView table.

Alternatively if you don't want to see whats changed but you want to see the final state, you could copy the MSI to a temporary MSI and use the ApplyTransform method to apply the transform and then commit it. Now you could query it using the code you already have.

Edit a msi database table

Although tools such as msidb.exe are capable of exporting and importing text archive files, text archive files should only be used for the following specific purposes.

  • Text archive files can be used with version control systems.
  • To remove wasted storage space and reduce the final size of .msi
    files.
  • To add localization information to an installation database.
  • To determine the code page of a database.
  • To set the code page of a database.
  • To increase the limit of a database column. Authors cannot change the
    column data types, nullability, or localization attributes of any
    columns in standard tables.

A text archive file for a Windows Installer database carries an .idt file name extension and is in the Archive File Format.

You should use a Windows Installer table editing tool, such as Orca or a third-party tool, to create and modify an installation package.



Related Topics



Leave a reply



Submit