C# – How to read data from .msi file?

Today I start a new small project on extracting file from .msi file. The reason I start this project is that sometimes I just want to run a program only once but it needs to install on my machine. I do not like that. For example, I would like to check if my computer is suitable for Windows 7 so I downloaded Windows 7 Upgrade Advisor and run it to test. After finising with download, I realized that it is a .msi file. That means I must install if I would like to use. So I search around to find an unpacker for MSI file but after some searching I decide to write my own one. I guess it is not so difficult to write a program to extract all files in .msi file.

In my first step, I searched for MSI file format specification but after hard searching in 30 minutes, I could not find any documenation about msi file format. I really hate Microsoft in some cases. Microsoft did not publish any documentation of some important file formats and protocols which they use in Windows. Before I have problem with MMS protocol and now with MSI, always no specification for them. :(. I thought I could not start my project because it is not easy to reverse a file format of a complex structure. Luckily Wikipedia leads me to a WIX.

The Windows Installer XML toolset, is a free software toolset that builds Windows Installer (MSI) packages from an XML document. It supports a command-line environment that developers may integrate into their build processes to build MSI and MSM setup packages. WiX was the first software released by Microsoft under an open-source license called Common Public License.

For more details, you can find at homepage of Wix. I just post below a small code snippet to access info from msi file.

string strFileMsi = "D:\\w7ua.msi";
string strFileMsiNameOnly = Path.GetFileNameWithoutExtension(strFileMsi);
string strDirectory = Path.GetDirectoryName(strFileMsi);
Database dbMsiFile = new Database(strFileMsi, OpenDatabase.ReadOnly);
View viewTemp = dbMsiFile.OpenExecuteView("SELECT * FROM Media");
Record rcTemp = viewTemp.Fetch();
string strCabsName = rcTemp[CNST_MEDIA_CABINET];
strCabsName = strCabsName.Substring(1);
viewTemp = dbMsiFile.OpenExecuteView("SELECT * FROM `_Streams` WHERE `Name` = '" + strCabsName + "'");
rcTemp = viewTemp.Fetch();

To view all available tables from msi file you can use Orca tool which is shipped with Windows Installer 4.5 SDK as figure below.

One thought on “C# – How to read data from .msi file?”

  1. Could you provide more details witch assembly are requred or at least the link to WiX page where the deyails coudl be found.

    I look on the WiX page and cant find such informations.

Leave a Reply

Your email address will not be published. Required fields are marked *