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?