10 ответов:
повторение раздела реестра "SOFTWARE\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, которые могут быть полезны для вас.
вы можете взглянуть на в этой статье. Он использует реестр для чтения списка установленных приложений.
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) { } } } } }
стоит отметить, что класс WMI Win32_Product представляет продукты, установленные установщиком Windows[http://msdn.microsoft.com/en-us/library/aa394378%28v=vs.85%29.aspx]. не каждое приложение использует установщик windows
однако "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" представляет приложения для 32 бит. Для 64 бит вам также нужно пройти "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" и поскольку не каждое программное обеспечение имеет 64-разрядную версию, общее количество установленных приложений представляет собой объединение ключей в обоих местах, которые имеют значение "UninstallString" с ними.
но лучшие варианты остаются прежними .траверс разделов реестра является лучшим подходом, так как каждое приложение имеет запись в реестре[в том числе в установщике Windows].однако метод реестра небезопасен, как будто кто-то удаляет соответствующий ключ, то вы не будете знать запись приложения.Напротив того Изменение установщиков с помощью функции "Win32\Installers" является более сложным, поскольку связано с проблемами лицензирования, такими как Microsoft office или другие продукты. для более надежного решения вы всегда можете объединить альтернативу реестра с WMI.
Я согласен, что перечисление через раздел реестра является лучшим способом.
Примечание, однако, что ключ дали,
@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", перечислит все приложения в 32-разрядной установке Windows и 64-разрядные приложения в 64-разрядной установке Windows.чтобы также увидеть 32-разрядные приложения, установленные на 64-разрядной установке Windows, вам также необходимо перечислить ключ
@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall".
выполните итерацию по ключам " HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall "и проверьте их значения" DisplayName".
могу я предложить вам взглянуть на WMI (Инструментарий Управления Windows). Если вы добавите систему.Управление ссылка на ваш проект C#, вы получите доступ к классу "ManagementObjectSearcher", который вы, вероятно, найдете полезным.
существуют различные классы WMI для Установленные Приложения, но если он был установлен с установщиком Windows, то класс Win32_Product, вероятно, лучше всего подходит для вас.
ManagementObjectSearcher s = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
используйте API установщика Windows!
Это позволяет сделать надежное перечисление всех программ. Реестр не является надежным, но WMI является тяжеловесом.
я использовал подход 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; }
лучше всего использовать WMI. В частности,win32_product запросов класса.
мое требование-проверить, установлено ли в моей системе определенное программное обеспечение. Это решение работает, как и ожидалось. Это может тебе помочь. Я использовал приложение windows в c# с 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; }
Comments