Home > database >  C#: Get Product Version using the Product Name using the WindowsInstaller and not WMI
C#: Get Product Version using the Product Name using the WindowsInstaller and not WMI

Time:08-25

I need some help in retrieving the ProductVersion of a program in C#. I did found a way to retrieve it using WMI but it is really slow.

Previously I had the same issue when using vbscript and the solution was to use the Windows Installer (which is really fast)

    Set objInstaller = CreateObject("WindowsInstaller.Installer")
    Set colProducts = objInstaller.Products

    For Each objProduct In colProducts
        strProductName = objInstaller.ProductInfo(objProduct, "ProductName")
        If strProductName = "MyProductName1" Then       
            var1 = objInstaller.ProductInfo(objProduct, "VersionString")
        End If
        If strProductName = "MyProductName2" Then       
            var2 = objInstaller.ProductInfo(objProduct, "VersionString")
        End If              
    Next

The question is how to I do the same in C#? I'm currently using Avalonia as Ui.

I also tried also all the other methods in the search (Wix DTF, COM with P/Invoke), so please don't redirect to google....

Edit: I do not have a path for the msi or exe. I need to search in the registry or installer that is why getfileversion or dtf is not working.

Thanks!

CodePudding user response:

There are many ways to do this. Using WiX DTF should be relatively easy, but you might not want the dependency on the DTF dlls? If so you can use interop and call the C API directly (no custom assembly dependencies).

For the DTF scenario (too late to add the C api call version tonight) you create a new project, then you add project references to the WiX DTF assemblies (standard path is: "C:\Program Files (x86)\WiX Toolset v3.11\bin"). The files you need are:

  • Microsoft.Deployment.WindowsInstaller.dll
  • Microsoft.Deployment.WindowsInstaller.Package.dll

Then you can try this code snippet - consult the DTF help file for more details - the help file you will find in the WiX installation folder ("doc" sub-folder):

using System;
using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Deployment.WindowsInstaller.Package;

namespace DTFTestApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            InstallPackage pkg = new InstallPackage(@"e:\MySetup.msi", DatabaseOpenMode.ReadOnly);
            var version = pkg.Property["ProductVersion"];
            Console.WriteLine(version);
        }
    }
}

Links:

CodePudding user response:

thank you for the replies, here is my code after reading all the comments and resources.

public class Program
{
    public static string getInstalledVersion(string findByName)
    {
        string info = null;
        string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";

        RegistryKey key64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
        RegistryKey key = key64.OpenSubKey(registryKey);

        if (key != null)
        {
            foreach (RegistryKey subkey in key.GetSubKeyNames().Select(keyName => key.OpenSubKey(keyName)))
            {
                string displayName = subkey.GetValue("DisplayName") as string;

                if (displayName != null && displayName.Contains(findByName))
                    info = subkey.GetValue("Version").ToString();
                else
                    info = "Not found";
            }
            key.Close();
        }
        return info;
    }
}

Get the result in a variable:

public string MyVar => Program.getInstalledVersion("Microsoft Edge");

Trying to get this to work but I only get "Not found". What am I missing?

  • Related