Получить установленные приложения в системе - программирование

Получить установленные приложения в системе

Как получить приложения, установленные в системе, с помощью кода С#?

4b9b3361

Ответ 1

Итерирование через раздел реестра "ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ \Microsoft\Windows\CurrentVersion\Uninstall", похоже, дает полный список установленных приложений.

Помимо приведенного ниже примера, вы можете найти аналогичную версию того, что я сделал здесь.

Это пример, вы, вероятно, захотите сделать что-то, чтобы вырезать пустые строки, например, во 2-й ссылке.

string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using(Microsoft.Win32.RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
{
    foreach(string subkey_name in key.GetSubKeyNames())
    {
        using(RegistryKey subkey = key.OpenSubKey(subkey_name))
        {
            Console.WriteLine(subkey.GetValue("DisplayName"));
        }
    }
}

В качестве альтернативы вы можете использовать WMI, как было упомянуто:

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

Но это выполняется довольно медленнее, и я слышал, что он может отображать только программы, установленные под "ALLUSERS", хотя это может быть неверно. Он также игнорирует компоненты Windows и обновления, которые могут вам пригодиться.

Ответ 2

Вы можете взглянуть на в этой статье. Он использует реестр для чтения списка установленных приложений.

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
                {
                    lstInstalled.Items.Add(sk.GetValue("DisplayName"));
                }
                catch (Exception ex)
                { }
            }
        }
    }
}

Ответ 3

Я согласен с тем, что перечисление через ключ реестра - лучший способ.

Примечание, однако, что указанный ключ @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" отобразит все приложения в 32-разрядной установке Windows и 64-разрядные приложения в 64-разрядной установке Windows.

Чтобы также увидеть 32-разрядные приложения, установленные в 64-разрядной установке Windows, вам также нужно будет перечислить ключ @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall".

Ответ 4

Стоит отметить, что класс WMI Win32_Product представляет продукты в том виде, как они установлены установщиком Windows. не каждое приложение использует Windows Installer

однако "ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ \Microsoft\Windows\CurrentVersion\Uninstall" представляет приложения для 32-разрядных. Для 64-битной версии вам также нужно пройти "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall", и, поскольку не у каждого программного обеспечения есть 64-битная версия, общее количество установленных приложений представляет собой объединение ключей в обоих расположениях с "UninstallString". Ценность с ними.

но лучшие варианты остаются теми же. Ключи реестра .traverse - лучший подход, так как у каждого приложения есть запись в реестре [включая записи в установщике Windows]. Однако метод реестра небезопасен, как если бы кто-то удалял соответствующий ключ, тогда вы не узнаете Запись приложения. Напротив, изменение HKEY_Classes_ROOT\Installers более сложно, поскольку оно связано с проблемами лицензирования, такими как Microsoft office или другие продукты. для более надежного решения вы всегда можете объединить альтернативу реестра с WMI.

Ответ 5

Перейдите через ключи "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" и проверьте их значения "DisplayName".

Ответ 6

Использовать Windows Installer API!

Это позволяет сделать надежное перечисление всех программ. Реестр не надежный, но WMI - тяжеловес.

Ответ 7

Лучше всего использовать WMI. В частности, класс Win32_Product.

Ответ 8

Могу я предложить вам взглянуть на WMI (Инструмент управления Windows). Если вы добавите ссылку System.Management в ваш проект С#, вы получите доступ к классу "ManagementObjectSearcher", который вы, вероятно, найдете полезным.

Существуют различные классы WMI для Установленные приложения, но если он был установлен с установщиком Windows, то класс Win32_Product, вероятно, лучше всего подходит для вы.

ManagementObjectSearcher s = new ManagementObjectSearcher("SELECT * FROM Win32_Product");

Ответ 9

Я использовал подход Nicks - мне нужно было проверить, установлены ли удаленные инструменты для Visual Studio или нет, это кажется немного медленным, но в отдельном потоке это нормально для меня. - здесь мой расширенный код:

    private bool isRdInstalled() {
        ManagementObjectSearcher p = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
        foreach (ManagementObject program in p.Get()) {
            if (program != null && program.GetPropertyValue("Name") != null && program.GetPropertyValue("Name").ToString().Contains("Microsoft Visual Studio 2012 Remote Debugger")) {
                return true;
            }
            if (program != null && program.GetPropertyValue("Name") != null) {
                Trace.WriteLine(program.GetPropertyValue("Name"));
            }
        }
        return false;
    }

Ответ 10

Мое требование - проверить, установлено ли в моей системе определенное программное обеспечение. Это решение работает так, как ожидалось. Это может помочь вам. Я использовал приложение Windows в С# с visual studio 2015.

 private void Form1_Load(object sender, EventArgs e)
        {

            object line;
            string softwareinstallpath = string.Empty;
            string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
            using (var baseKey = Microsoft.Win32.RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
            {
                using (var key = baseKey.OpenSubKey(registry_key))
                {
                    foreach (string subkey_name in key.GetSubKeyNames())
                    {
                        using (var subKey = key.OpenSubKey(subkey_name))
                        {
                            line = subKey.GetValue("DisplayName");
                            if (line != null && (line.ToString().ToUpper().Contains("SPARK")))
                            {

                                softwareinstallpath = subKey.GetValue("InstallLocation").ToString();
                                listBox1.Items.Add(subKey.GetValue("InstallLocation"));
                                break;
                            }
                        }
                    }
                }
            }

            if(softwareinstallpath.Equals(string.Empty))
            {
                MessageBox.Show("The Mirth connect software not installed in this system.")
            }



            string targetPath = softwareinstallpath + @"\custom-lib\";
            string[] files = System.IO.Directory.GetFiles(@"D:\BaseFiles");

            // Copy the files and overwrite destination files if they already exist. 
            foreach (var item in files)
            {
                string srcfilepath = item;
                string fileName = System.IO.Path.GetFileName(item);
                System.IO.File.Copy(srcfilepath, targetPath + fileName, true);
            }
            return;

        }

Ответ 11

Я хотел иметь возможность извлекать список приложений так же, как они появляются в меню "Пуск". Используя реестр, я получал записи, которые не отображаются в меню "Пуск".

Я также хотел найти путь к exe файлу и извлечь значок, чтобы в итоге создать красивый лаунчер. К сожалению, при использовании метода реестра это является хитом, поскольку, по моим наблюдениям, эта информация не является надежно доступной.

Моя альтернатива основана на оболочке: AppsFolder, к которой вы можете получить доступ, запустив explorer.exe shell:appsFolder и в которой перечислены все приложения, включая приложения магазина, установленные и доступные в данный момент через меню "Пуск". Проблема в том, что это виртуальная папка, к которой нельзя получить доступ с помощью System.IO.Directory. Вместо этого вам придется использовать собственные команды shell32. К счастью, Microsoft опубликовала Microsoft.WindowsAPICodePack-Shell на Nuget, которая является оболочкой для вышеупомянутых команд. Достаточно сказано, вот код:

// GUID taken from https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid
var FODLERID_AppsFolder = new Guid("{1e87508d-89c2-42f0-8a7e-645a0f50ca58}");
ShellObject appsFolder = (ShellObject)KnownFolderHelper.FromKnownFolderId(FODLERID_AppsFolder);

foreach (var app in (IKnownFolder)appsFolder)
{
    // The friendly app name
    string name = app.Name;
    // The ParsingName property is the AppUserModelID
    string appUserModelID = app.ParsingName; // or app.Properties.System.AppUserModel.ID
    // You can even get the Jumbo icon in one shot
    ImageSource icon =  app.Thumbnail.ExtraLargeBitmapSource;
}

И это все, что нужно сделать. Вы также можете запустить приложения, используя

System.Diagnostics.Process.Start("explorer.exe", @" shell:appsFolder\" + appModelUserID);

Это работает для обычных приложений Win32 и приложений магазина UWP. Как насчет яблок?

Поскольку вы заинтересованы в перечислении всех установленных приложений, разумно ожидать, что вы, возможно, захотите отслеживать новые приложения или также неустановленные приложения, что можно сделать с помощью ShellObjectWatcher:

ShellObjectWatcher sow = new ShellObjectWatcher(appsFolder, false);
sow.AllEvents += (s, e) => DoWhatever();
sow.Start();

Изменить. Также может быть интересно узнать, что упомянутый выше AppUserMoedlID является уникальным идентификатором, который Windows использует для группировки окон на панели задач.

Ответ 12

Пока принятое решение работает, оно не является полным. Безусловно.

Если вы хотите получить все ключи, вам нужно учесть еще 2 вещи:

x86 & Приложения x64 не имеют доступа к одному и тому же реестру. Обычно x86 не может нормально обращаться к реестру x64. И немного приложения регистрируются только в реестре x64.

и

некоторые приложения фактически устанавливаются в реестр CurrentUser вместо LocalMachine

Имея это в виду, мне удалось получить ВСЕ установленные приложения, используя следующий код, БЕЗ, используя WMI

Вот код:

List<string> installs = new List<string>();
List<string> keys = new List<string>() {
  @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
  @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
};

// The RegistryView.Registry64 forces the application to open the registry as x64 even if the application is compiled as x86 
FindInstalls(RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64), keys, installs);
FindInstalls(RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64), keys, installs);

installs = installs.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList();
installs.Sort(); // The list of ALL installed applications



private void FindInstalls(RegistryKey regKey, List<string> keys, List<string> installed)
{
  foreach (string key in keys)
  {
    using (RegistryKey rk = regKey.OpenSubKey(key))
    {
      if (rk == null)
      {
        continue;
      }
      foreach (string skName in rk.GetSubKeyNames())
      {
        using (RegistryKey sk = rk.OpenSubKey(skName))
        {
          try
          {
            installed.Add(Convert.ToString(sk.GetValue("DisplayName")));
          }
          catch (Exception ex)
          { }
        }
      }
    }
  }
}