Search code examples
c#comwindows-installer

Get primary keys from MSI table using msi.dl in c#


I have a problem with calling get_PrimaryKeys() function from msi.dll in c#. I want to fund out what are the primary keys in a given MSI table. I use the following code:

Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
installer = (Installer)Activator.CreateInstance(installerType);
database = installer.OpenDatabase(MSIPath, MsiOpenDatabaseMode.msiOpenDatabaseModeTransact);
WindowsInstaller.Record data = null;     
data = database.PrimaryKeys[tableName];
string s = data.get_StringData(1);

If I use database.get_PrimaryKeys(tableName), it gives the same error which is:

COMexception
Member not found. (Exception from HRESULT: 0x80020003 (DISP_E_MEMBERNOTFOUND))

When I use other functions form msi.dll they works fine.

What is the problem?


Solution

  • There's an easier way to query MSI database from C# code. The WiX Toolset includes a well-designed convenient .NET API called DTF (Deployment Tools Foundation), which makes is possible to write the following (C#):

      using (var database = new Database("path\\to\\package.msi", DatabaseOpenMode.ReadOnly))
      {
        var table = database.Tables["someTableName"];
        foreach (var column in table.PrimaryKeys)
        {
          Console.WriteLine("The table {0} defines {1} as primary key", table.Name, column);
        }
      }
    

    All you have to do:

    • install WiX Toolset
    • reference Microsoft.Deployment.WindowsInstaller.dll in your C# project
    • add using Microsoft.Deployment.WindowsInstaller; namespace

    You don't have to build your MSI with WiX in order to get advantage out of DTF. Reference DTF.chm (installed together with WiX) to know more about it.