Read Properties from an MSI File

Today I was working writing auto-updating for some software. I wanted to base it on the Product Version property in the installer MSI file, so I needed some code to read that from the file.

It took a fair amount of searching and code tweaking, but I finally worked it all out.

  1. Add a reference to the COM Microsoft Windows Installer Object Library.
  2. Add a using WindowsInstaller;
  3. Add the following static method to your code (error checking removed for brevity.)
public static string GetMsiProperty( string msiFile, string property )
   string retVal = string.Empty;

   // Create an Installer instance
   Type classType = Type.GetTypeFromProgID( “WindowsInstaller.Installer” );
   Object installerObj = Activator.CreateInstance( classType );
   Installer installer = installerObj as Installer;

   // Open the msi file for reading
   // 0 - Read, 1 - Read/Write
   Database database = installer.OpenDatabase( msiFile, 0 );

   // Fetch the requested property
   string sql = String.Format(
      “SELECT Value FROM Property WHERE Property=’{0}’”, property );
   View view = database.OpenView( sql );
   view.Execute( null );

   // Read in the fetched record
   Record record = view.Fetch();
   if ( record != null )
      retVal = record.get_StringData( 1 );

   return retVal;

If you want to look up the version, just pass in the name of the MSI file you want to inspect and “ProductVersion” for the property you want to return. For example;

string version = GetMsiProperty( msiFile, “ProductVersion” );

You can use this method to look up other properties in the installer. Some common ones you might want are ProductName, ProductCode, UpgradeCode, Manufacturer, ARPHELPLINK, ARPCOMMENTS, ARPCONTACT, ARPURLINFOABOUT and ARPURLUDATEINFO. For a full list of properties, see the MSDN Reference, but remember that most of the properties listed on that page are only for already installed applications and won’t be included in the installer.

If you find this code useful or the code is not self-explanatory, please leave a comment.

  • Johan Gunnarsson

    didn’t get this to work, although this was a while ago, however here’s a more recent link which does the job:

  • Archana

    Thank you so much.Very useful.

  • Thomas Kristensen


    Great post, but I got a problem trying to add refrences to Microsoft Windows Installer Object Libray. It tells me that isnt registered. (TYPE_E_LIBNOTREGISTERED)

    What to do?

  • Pravin

    Very useful. Thanks!!!

  • Fan

    Awesome article! Thanks so much!

  • The post has been updated. I do read my comments, but occasionally I miss a few.

  • Whatever

    Mike and Neo are correct, you MUST correct your SQL string in your code, as it generates a COM exception. Don’t you read your comments?

    So much for a “consulting” business…

  • PeterG

    Thank you, thank you, thank you!!! I’ve fond this code in lots of places, but nowhere does it say what the assemly that you nood to include is! I was about to search through every .NET and COM assembly included, but then I found your article and was saved!

    Again, Thank you!

  • Here is an improved version of the above code. This new versions allows to pass in a dictionary of property names whose values are then filled in.

    /// Uses the Windows Installer COM component to retrieve property values (e.g. ProductCode) from an MSI file.
    /// The path to an MSI file.
    /// A dictionary containing the property names whose values need to be retrieved and filled in from the MSI file.
    public static void GetMsiProperties(string msiFile, SortedDictionary propertyNames)
    if (string.IsNullOrEmpty(msiFile))
    throw new ArgumentException(Resources.ErrBlankMsiFilePath, “msiFile”);

    if (propertyNames == null || propertyNames.Count == 0)
    throw new ArgumentException(Resources.ErrNullOrEmptyPropertyNamesDictionary, “propertyNames”);

    Type classType = Type.GetTypeFromProgID(“WindowsInstaller.Installer”);
    Object installerObj = Activator.CreateInstance(classType);
    Installer installer = (Installer)installerObj;

    // Open the msi file for reading : 0 – Read, 1 – Read/Write
    Database database = installer.OpenDatabase(msiFile, 0);
    StringBuilder sql = new StringBuilder(“SELECT Property, Value FROM Property WHERE “);

    foreach (KeyValuePair item in propertyNames)
    sql.AppendFormat(“Property = ‘{0}’ OR “, item.Key);

    sql.Remove(sql.Length – 4, 4); // remove last ” OR ”

    View view = database.OpenView(sql.ToString());

    Record record = view.Fetch();
    while (record != null)
    propertyNames[record.StringData[1]] = record.StringData[2];
    record = view.Fetch();


  • kabilan

    thank for all…. its very helpful

  • Jo

    This was very helpful! Thank You!

  • Sam

    Really good!非常棒

  • Neo

    Mike is right.

  • Mike

    I was getting an interop exception on the OpenView method when I tried this code. I tracked it down to the SQL statement. Removing the single quotes from the reference to the Value column and the Properties table fixed the code.

  • matju

    can we edit or modify the .msi file.???
    coz i want rebuilt that software by my own

  • Hans Christian

    Thanks for the code, Robert!

    But I too encountered the deletion problem. A colleague of mine searched and found the (somewhat unintuitive…) solution. Before returning from GetMsiProperty, do:

    if (record != null)

  • Krystian Kapel

    I’ve read your post on Alteridem Consulting Website about reading properties from an MSI file.
    I use GetMsiProperty function to find out MSI file version, but I encouraged a problem while trying to delete file after I’ve checked it’s version.
    It seems like the file is still in use by GetMsiProperty function. I tried to find some closing function but I didn’t succeed.

    Maybe you know something I forgot to do while reading Msi version?

    I would appriciate any help.