Reputation: 7388
I'm developing a scheme to automatically update my program from a central point. To assist me in this I need a way to get the version # of the msi file used to install the progarm at runtime, so I can compare the installed version with the latest version on the server (already solved this part) and decide whether or not to update. To be clear, I already have a way of opening up msi files using msi.dll and getting the version # out. The problem is one of bootstrapping. If the user installs the program for the very first time, how can my program know where to find the msi file (on the client)?
The solution can be as simple as the msi creating a text file with the version # in it when it runs. I'd like to avoid querying the registry if I can.
If I can't figure this out I'm going to have to take special care to keep the version #'s the same in the GUI project and also the MSI installer, and that thought annoys me.
Any thoughts?
Upvotes: 2
Views: 3529
Reputation: 1061
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
registry key contains ProductCode subkeys of installed programs. Control Panel's "Add/Remove Problems" and MSI Engine work with this branch.
Iterating through these subkeys you can find the GUID of your program (if you keep old value when changing version in Setup-and-Deployment project). Under that subkey 'DisplayVersion' string value will contain installed version (corresponds to 'Version' property in SnD project).
If you do change ProductCode when increasing Version number (as VisualStudio recommends), 'DisplayName' string may be useful for figuring out which subkey is representing your program, it corresponds to 'ProductName' property in SnD project.
Some programs may be listed in HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
when installed on a per-user basis (e.g. via ClickOnce).
On 64-bit systems there's HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
for 32-bit programs in addition to the original, which in that environment keeps track of 64-bit ones.
Upvotes: 0
Reputation: 808
I assume you want to get the ProductVersion property of the MSI.
You can do this fairly easily using COM.
Add a COM reference to "Microsoft Windows Installer Object Library" to your C# project.
Then try the following program:
namespace TestCS
{
using System;
using WindowsInstaller;
internal class Test
{
private static void Main(string[] args)
{
if (args.Length < 1)
{
return;
}
Console.WriteLine(GetMsiVersion(args[0]));
}
private static string GetMsiVersion(string installerPath)
{
Type t = Type.GetTypeFromProgID("WindowsInstaller.Installer");
Installer inst = (Installer)Activator.CreateInstance(t);
Database d = inst.OpenDatabase(
installerPath,
MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly);
View v = d.OpenView(
"SELECT * FROM Property WHERE Property = 'ProductVersion'");
v.Execute(null);
Record r = v.Fetch();
string result = r.get_StringData(2);
return result;
}
}
}
Upvotes: 5