You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中借助Windows Installer而非WMI通过产品名获取产品版本?

C#快速获取已安装程序的ProductVersion(替代WMI方法)

背景需求

之前用VBS通过Windows Installer可快速获取已安装程序的版本信息,但WMI方法速度极慢。现在需要在C#(基于Avalonia UI框架)中实现相同功能,且没有目标程序的MSI或EXE文件路径,因此GetFileVersion或Wix DTF方法无法使用。

对应的VBS实现代码:

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

尝试过程

Edit1:首次编写注册表查询代码

最初尝试通过32位注册表路径查询,但存在逻辑问题(break未加括号导致提前退出),且查询的注册表项错误:

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;
    }
}

调用方式:

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

Edit2:修复逻辑后仍存在问题,尝试ProductInstallation方法

添加break的括号后能找到Microsoft Edge,但无法识别其他程序;尝试使用ProductInstallation方法也未生效:

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;
    }
}

调用方式:

public string MyProgram => ProgramX.getPVersion("Microsoft Edge");

Edit3:最终解决方案

问题根源在于:

  1. 注册表中存储版本信息的键是DisplayVersion而非Version
  2. 需要查询64位注册表路径(无需额外指定WOW6432Node,通过RegistryView.Registry64自动处理)

最终代码:

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;
    }
}

内容的提问来源于stack exchange,提问作者Lodes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 19:27:16