使用C#获取已安装软件列表

10

我尝试获取已安装应用程序的密钥列表:

RegistryKey RegKeyUninstallList = Registry.LocalMachine;
string strUninstallList = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
string[] test = RegKeyUninstallList.OpenSubKey(strUninstallList).GetSubKeyNames();

我只能从以下位置获取密钥:

  

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

但我也需要从以下位置获取密钥:

  

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

我的程序应该能够在 64位32位 的计算机上运行。

编辑:好的,我尝试了检查注册表中是否安装了应用程序和tHiNk_OuT_oF_bOx的解决方案。

但什么都没解决问题!

问题是测试和测试2的列表完全相同:

RegistryKey RegKeyUninstallList = Registry.LocalMachine;
string strUninstallList = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
string strUninstallList2 = @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
string[] test = RegKeyUninstallList.OpenSubKey(strUninstallList).GetSubKeyNames();
string[] test2 = RegKeyUninstallList.OpenSubKey(strUninstallList2).GetSubKeyNames();

1
你不应该使用WMI吗?http://technet.microsoft.com/zh-cn/library/ee156540.aspx - David Brabant
6个回答

13

来源: http://social.msdn.microsoft.com/Forums/en-US/94c2f14d-c45e-4b55-9ba0-eb091bac1035/c-get-installed-programs

解决方案是在注册表中搜索3个位置:

  1. CurrentUser中的SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
  2. LocalMachine中的SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
  3. LocalMachine中的SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

以下代码适合您的需求。

public static bool IsApplicationInstalled(string p_name)
{
    string displayName;
    RegistryKey key;

    // search in: CurrentUser
    key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
    foreach (String keyName in key.GetSubKeyNames())
    {
        RegistryKey subkey = key.OpenSubKey(keyName);
        displayName = subkey.GetValue("DisplayName") as string;
        if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)
        {
            return true;
        }
    }

    // search in: LocalMachine_32
    key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
    foreach (String keyName in key.GetSubKeyNames())
    {
        RegistryKey subkey = key.OpenSubKey(keyName);
        displayName = subkey.GetValue("DisplayName") as string;
        if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)
        {
            return true;
        }
    }

    // search in: LocalMachine_64
    key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
    foreach (String keyName in key.GetSubKeyNames())
    {
        RegistryKey subkey = key.OpenSubKey(keyName);
        displayName = subkey.GetValue("DisplayName") as string;
        if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)
        {
            return true;
        }
    }

    // NOT FOUND
    return false;
}

5
请使用 RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, is64bit ? RegistryView.Registry64 : RegistryView.Registry32); 替代 Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node...")。 ;) - Xaruth
3
@Xaruth 谢谢你,它与 ´RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, is64bit ? RegistryView.Registry64 : RegistryView.Registry32)´ 配合使用。 - user3523585
请求的注册表访问不被允许 :( 有什么解决方案吗? - Ahmad
@Xaruth 当我们使用你的代码时,它会显示安全异常。 - Ahmad

5

看起来现在必须使用OpenBaseKey,这是我正在使用的代码:

List<string> gInstalledSoftware
        void GetInstalledSoftwareList()
        {
            string displayName;

            using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", false))
            {                
                foreach (String keyName in key.GetSubKeyNames())
                {
                    RegistryKey subkey = key.OpenSubKey(keyName);
                    displayName = subkey.GetValue("DisplayName") as string;
                    if (string.IsNullOrEmpty(displayName))
                        continue;

                    gInstalledSoftware.Add(displayName.ToLower());
                }
            }

            //using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", false))
            using (var localMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
            {
                var key = localMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", false);
                foreach (String keyName in key.GetSubKeyNames())
                {
                    RegistryKey subkey = key.OpenSubKey(keyName);
                    displayName = subkey.GetValue("DisplayName") as string;
                    if (string.IsNullOrEmpty(displayName))
                        continue;

                    gInstalledSoftware.Add(displayName.ToLower());
                }
            }

            using (var localMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
            {
                var key = localMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", false);
                foreach (String keyName in key.GetSubKeyNames())
                {
                    RegistryKey subkey = key.OpenSubKey(keyName);
                    displayName = subkey.GetValue("DisplayName") as string;
                    if (string.IsNullOrEmpty(displayName))
                        continue;

                    gInstalledSoftware.Add(displayName.ToLower());
                }
            }

            using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall",false))
            {
                foreach (String keyName in key.GetSubKeyNames())
                {
                    RegistryKey subkey = key.OpenSubKey(keyName);
                    displayName = subkey.GetValue("DisplayName") as string;
                    if (string.IsNullOrEmpty(displayName))
                        continue;

                    gInstalledSoftware.Add(displayName.ToLower());
                }
            }             
        } 

2

我使用了以下代码,它比较抽象,并检查32/64位操作系统。同时为了简单起见,它还使用了C#V8功能。

public static bool CheckAppInstallation(string programName)
{
    bool result = false;
    string uninstallKey1 = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
    string uninstallKey2 = @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
    result |= CheckInAddress(uninstallKey1, RegistryHive.LocalMachine, programName);
    result |= CheckInAddress(uninstallKey1, RegistryHive.CurrentUser, programName);
    result |= CheckInAddress(uninstallKey2, RegistryHive.LocalMachine, programName);
    return result;

    static bool CheckInAddress(string address, RegistryHive hive, string programName)
    {
        var view = Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32;
        using var localKey = RegistryKey.OpenBaseKey(hive, view).OpenSubKey(address);
        foreach (var subKey in localKey.GetSubKeyNames().Select(keyName => localKey.OpenSubKey(keyName)))
            if (subKey.GetValue("DisplayName") is string displayName && displayName.Contains(programName))
                return true;
        return false;
    }
}

2

所有的答案都无法检索到 Windows 10 上安装的每个应用程序。上面的代码只显示最常用的已安装应用程序而非所有已安装的应用程序。因此,我找到了以下解决方案:

string appPATH = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
            using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(appPATH))
            {
                foreach (string skName in rk.GetSubKeyNames())
                {
                    using (RegistryKey sk = rk.OpenSubKey(skName))
                    {
                        try
                        {

                            //Get App Name
                            var displayName = sk.GetValue("DisplayName");
                            //Get App Size
                            var size = sk.GetValue("EstimatedSize");

                            string item;
                            if (displayName != null)
                            {
                                if (size != null)
                                    item = displayName.ToString();
                                else
                                {
                                    item = displayName.ToString();
                                    if (item.Contains(""))
                                    MessageBox.Show(displayName.ToString());

                                }

                            }
                        }
                        catch (Exception ex)
                        { }
                    }
                }

            }

1
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using Microsoft.Win32;


public void GetInstalledApps()  
{  
   string uninstallKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";  
   using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(uninstallKey))  
   {  
       foreach (string skName in rk.GetSubKeyNames())  
       {  
           using (RegistryKey sk = rk.OpenSubKey(skName))  
           {  
               try  
               {    
                  listBox1.Items.Add(sk.GetValue("DisplayName"));                             
               }  
               catch (Exception ex)  
               { }  
           }  
       }  
       label1.Text = listBox1.Items.Count.ToString();  
   }  
}   

使用 Microsoft.VisualBasic; - Xaruth
只是在VB.NET中编写,然后转换为C#。 - Suji

0

你能尝试在你的项目中添加引用 "System.Management",然后使用以下代码:

我认为更简单

ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
foreach (ManagementObject mo in mos.Get())
{
     Console.WriteLine(mo["Name"]);
}

嗨,这将仅返回Microsoft安装的产品列表,而不是所有产品。 - Krutika Patel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接