Search code examples
c#windows-installer

Inserting to an msi database from c#


I am trying to insert a new property into the msi file. I am able to update the msi database file using the following code.Is there a way to add new values into a table. I am not able to find any.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WindowsInstaller;

namespace msiExample
{
[System.Runtime.InteropServices.ComImport(), System.Runtime.InteropServices.Guid("000C1090-0000-0000-C000-000000000046")]
class Installer { }
class msiMain
{
    static void Main(string[] args)
    {
     WindowsInstaller.Installer ins = (WindowsInstaller.Installer)new Installer();

            string strFileMsi = @"C:\APP.msi";

           System.Console.WriteLine("STARTING SECOND QUERY");
            Database db2 = ins.OpenDatabase(strFileMsi, WindowsInstaller.MsiOpenDatabaseMode.msiOpenDatabaseModeDirect);
            View vw2 = db2.OpenView(@"Select * FROM Property where Value='Unknown'");  

            vw2.Execute(null);

            Record rcrd2 = vw2.Fetch();
            while (rcrd2 != null)
            {
                System.Console.WriteLine(rcrd2.get_StringData(1));
                rcrd2.set_StringData(1,"No data");
                vw2.Modify(WindowsInstaller.MsiViewModify.msiViewModifyUpdate, rcrd2);

                rcrd2 = vw2.Fetch();

            }               
            db2.Commit();
            vw2.Close();
            System.Console.WriteLine("completed");   
    }
  }
}

Solution

  • Windows Installer XML (WiX) Deployment Tools Foundation (DTF) libraries help a lot here. The easiest way I know to do it is:

    using Microsoft.Deployment.WindowsInstaller.Linq;
    using (QDatabase database = new QDatabase(@"C:\data\test.msi", DatabaseOpenMode.Direct))
    {
      var record = database.Properties.NewRecord();
      record.Property = "MyProperty";
      record.Value = "MyValue";
      record.Insert();
    }
    

    If you still want to think SQL then:

    using Microsoft.Deployment.WindowsInstaller;
    using (Database database = new Database(@"C:\data\test.msi", DatabaseOpenMode.Direct))
    {
      database.Execute("INSERT INTO `Property` (`Property`, `Value`) VALUES('MyProperty', 'MyValue')");
    }