[Edit May 2008] I no longer use MSI.Interop. That interop was full of bugs, lacked many features and was no longer actively being developed or supported. Instead I reccomend the new DTF SDK from Microsoft as released by WiX. DTF brings a new Microsoft.Deployment.WindowsInstaller library that just runs circles around MSI.Interop.
One of the nice things about Per-Machine installations is that they are always managed. So provided that you get your ducks in a row following proper design patterns ( for example: Deferred Custom actions with the msidbCustomActionTypeNoImpersonate execute option and the SecureCustomProperties property ) you can simply advertise the package with the msiexec /JM command or run it as an Administrator and future upgrades can be serviced from the same source location without Administrative privileges by simply executing the update package with the REINSTALLMODE=vomus REINSTALL=ALL properties.
But wouldn't it be nice if the user didn't have to manually run the installation to perform the upgrade? Well, they don't. :) When you install your application you can save the OriginalDatabase or the ProductCode property somewhere your application can access it. With this information available to your application at runtime you can go find the MSI database and determine if there is a newer version available.
The following example in C# uses MSI.Interop.
static void Main(string args)
string msiPath = "C:\\TestApp.msi"; // Get this as described in the blog
Pahvant.MSI.Database database = new Pahvant.MSI.Database( msiPath, Pahvant.MSI.Database.OpenMode.ReadOnly );
Pahvant.MSI.View view = new Pahvant.MSI.View( database, "select `Value` from `Property` where `Property`='ProductVersion'");
Record record = view.Fetch();
string productVersion = record.GetString(1);
if( Application.ProductVersion != productVersion )
// Call Prompt For Upgrade Method
If your upgrade method, you'll probably want to shell out to msiexec async and terminate to avoid a locked file during Costing. Bonus points will be awarded by your user if you also pass a public property to indicate that an automatic upgrade is occuring so that your install restarts the application when it's finished upgrading.