I need some help in retrieving the ProductVersion of a program in C#. I did find 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 do I do the same in C#? I'm currently using Avalonia as UI.
I also tried 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!
Edit1: 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\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryKey key32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
RegistryKey key = key32.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();
break;
else
info = "Not found";
}
key.Close();
}
return info;
}
}
Get the result in a variable:
public string MyVar => Program.getInstalledVersion("Microsoft Edge");
Edit2: So the edit with the break in my latest version somewhat works. It finds Microsoft Edge but still doesn't find other programs (i will try other paths as fallbacks)
@ Stein Asmul i did try your version but doesn't find anything, maybe Im doing something wrong?
public class ProgramX
{
public static string getPVersion(string findByName)
{
string info = null;
foreach (var p in ProductInstallation.AllProducts)
{
if (p.ProductName == findByName)
{
info = p.ProductVersion.ToString();
break;
}
else
info = "Not Found";
}
return info;
}
}
Call:
public string MyProgram => ProgramX.getPVersion("Microsoft Edge");
Edit3: Great success! I managed to get it to work. The problem was subkey getvalue is "DisplayVersion" not "Version". I only need 64 for my programs.
public class ProgramI
{
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("DisplayVersion").ToString();
break;
}
else
info = "Not found";
}
key.Close();
}
return info;
}
}
Thanks everyone!