que puede programas los iconos icono funcion elementos desde cual control configurar conceptos cada c# .net windows registry controlpanel

puede - C#: ¿Cómo instalar los programas exactamente como en los programas y funciones del panel de control?



panel de control programas (4)

La clave de registro de SystemComponent que se analiza en otras respuestas aquí es generalmente un REG_DWORD con valores posibles de 0 o 1. Sin embargo, he visto un par de instancias (como Microsoft Visio 2010 y Microsoft Project 2010) donde SystemComponent es un REG_SZ sin datos . Por lo tanto, cualquier solución que convierta SystemComponent en un int puede generar una excepción en estas situaciones.

Leí mucha información de cómo obtener programas. Ninguno de los algoritmos hizo lo que quiero. Necesito instalar los programas exactamente como en el panel de control.

Así que utilicé:

  1. WMI Win32_Product class. Muestra solo los programas msi instalados.
  2. Claves de registro. HKLM/SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall . Nuevamente, algunos programas no se muestran en el panel de control, algunos programas se muestran en el panel de control no en este nodo de registro.

Entonces, ¿hay alguien en este mundo que supiera qué algoritmo usa el panel de control para mostrar los programas instalados?

UPD1: sí, uso 64 bits, sé que hay otro nodo para los programas instalados de 64 bits "HKLM / SOFTWARE / Wow6432Node / Microsoft / Windows / CurrentVersion / Uninstall" pero el siguiente código enumera twise HKLM / SOFTWARE / Wow6432Node / Microsoft / Windows / CurrentVersion / Desinstalar la sección, extraño ...

var programs = new List(); 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)) { var name = (string)subkey.GetValue("DisplayName"); if(!string.IsNullOrEmpty(name)) { programs.Add(name); } } } } registry_key = @"SOFTWARE/Wow6432Node/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)) { var name = (string)subkey.GetValue("DisplayName"); if (!string.IsNullOrEmpty(name)) { programs.Add(name); } } } } foreach (var program in programs.OrderBy(x => x)) { Console.WriteLine(program); }


La respuesta de MelnikovI es suficiente para la mayoría de los propósitos: tenía 144 artículos en mi lista y 143 en Programas y características. Para revisión , su solución es golpear estas ubicaciones de registro:

  • HKLM / Software / Microsoft / Windows / CurrentVersion / Uninstall
  • HKCU / Software / Microsoft / Windows / CurrentVersion / Uninstall
  • HKLM / Software / Wow6432Node / Microsoft / Windows / CurrentVersion / Uninstall

Para calificar, cada subclave DEBE tener:

  • El valor DisplayName REG_SZ

Y NO DEBE tener:

  • El SystemComponent REG_DWORD (distinto de cero)
  • Los valores ParentKeyName o ParentDisplayName REG_SZ
  • El valor de ReleaseType REG_SZ

La única mejora adicional que he encontrado es para las entradas de Windows Installer, definida como:

  • El nombre de la clave es una cadena GUID estándar
  • El WindowsInstaller REG_DWORD está presente (y no es cero)

Para tales entradas, puede tomar el paso adicional de usar la función Win32 MsiGetProductInfoW de msi.dll y solicitar la propiedad "VersionString" para el GUID representado por la clave.

Si esta función devuelve 1605: ERROR_UNKNOWN_PRODUCT , significa que la entrada no se instala de acuerdo con Windows Installer, y debe excluirse de la pantalla.

Después de implementar este pequeño ajuste, mi lista ahora es idéntica a Programas y Características.


Ok gyus, escribí una clase que puede obtener programas instalados desde el registro sin revisiones y actualizaciones. Todavía no es exactamente como en el panel de control pero casi . Espero que esto ayude a alguien más.

public static class InstalledPrograms { const string registry_key = @"SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall"; public static List<string> GetInstalledPrograms() { var result = new List<string>(); result.AddRange(GetInstalledProgramsFromRegistry(RegistryView.Registry32)); result.AddRange(GetInstalledProgramsFromRegistry(RegistryView.Registry64)); return result; } private static IEnumerable<string> GetInstalledProgramsFromRegistry(RegistryView registryView) { var result = new List<string>(); using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView).OpenSubKey(registry_key)) { foreach (string subkey_name in key.GetSubKeyNames()) { using (RegistryKey subkey = key.OpenSubKey(subkey_name)) { if(IsProgramVisible(subkey)) { result.Add((string)subkey.GetValue("DisplayName")); } } } } return result; } private static bool IsProgramVisible(RegistryKey subkey) { var name = (string)subkey.GetValue("DisplayName"); var releaseType = (string)subkey.GetValue("ReleaseType"); //var unistallString = (string)subkey.GetValue("UninstallString"); var systemComponent = subkey.GetValue("SystemComponent"); var parentName = (string)subkey.GetValue("ParentDisplayName"); return !string.IsNullOrEmpty(name) && string.IsNullOrEmpty(releaseType) && string.IsNullOrEmpty(parentName) && (systemComponent == null); } }


Tomé el código que MelnikovI escribió (que fue muy útil) y agregué un par de cosas. Primero, busque cuatro lugares en el registro:

HKLM / SOFTWARE / Microsoft / Windows / CurrentVersion / Uninstall

HKLM / SOFTWARE / Wow6432Node / Microsoft / Windows / CurrentVersion / Uninstall

HKCU / SOFTWARE / Microsoft / Windows / CurrentVersion / Uninstall

HKCU / SOFTWARE / Wow6432Node / Microsoft / Windows / CurrentVersion / Uninstall

También verifica si hay subclaves; si no, se salta esa.

Por último, hace una expresión regular para permitir solo un determinado conjunto de caracteres [^ a-zA-Z0-9. () + -].

Solo estoy comenzando en C #, así que no sabía una manera de recorrer las cuatro ubicaciones de registro, así que tengo dos bucles (uno para HKLM y otro para HKCU).

public static class InstalledPrograms { public static List<string> GetInstalledPrograms() { var result = new List<string>(); result.AddRange(GetInstalledProgramsFromRegistry(RegistryView.Registry32)); result.AddRange(GetInstalledProgramsFromRegistry(RegistryView.Registry64)); result.Sort(); return result; } private static string cleanText(string dirtyText) { Regex rgx = new Regex("[^a-zA-Z0-9 .()+-]"); string result = rgx.Replace(dirtyText, ""); return result; } private static IEnumerable<string> GetInstalledProgramsFromRegistry(RegistryView registryView) { var result = new List<string>(); List<string> uninstall = new List<string>(); uninstall.Add(@"SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall"); uninstall.Add(@"SOFTWARE/Wow6432Node/Microsoft/Windows/CurrentVersion/Uninstall"); foreach (string registry_key in uninstall) { using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView).OpenSubKey(registry_key)) { foreach (string subkey_name in key.GetSubKeyNames()) { using (RegistryKey subkey = key.OpenSubKey(subkey_name)) { if (IsProgramVisible(subkey)) { result.Add(cleanText(subkey.GetValue("DisplayName").ToString()).ToString()); } } } } using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, registryView).OpenSubKey(registry_key)) { if (key != null) { foreach (string subkey_name in key.GetSubKeyNames()) { using (RegistryKey subkey = key.OpenSubKey(subkey_name)) { if (IsProgramVisible(subkey)) { result.Add(cleanText(subkey.GetValue("DisplayName").ToString()).ToString()); } } } } } } return result; }

Si alguien está interesado, comparé los resultados con el PowerShell que he estado usando y son los mismos.

##Get list of Add/Remove programs if (!([Diagnostics.Process]::GetCurrentProcess().Path -match ''//syswow64//')) { $uninstallPath = "/SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall/" $uninstallWow6432Path = "/SOFTWARE/Wow6432Node/Microsoft/Windows/CurrentVersion/Uninstall/" @( if (Test-Path "HKLM:$uninstallWow6432Path" ) { Get-ChildItem "HKLM:$uninstallWow6432Path"} if (Test-Path "HKLM:$uninstallPath" ) { Get-ChildItem "HKLM:$uninstallPath" } if (Test-Path "HKCU:$uninstallWow6432Path") { Get-ChildItem "HKCU:$uninstallWow6432Path"} if (Test-Path "HKCU:$uninstallPath" ) { Get-ChildItem "HKCU:$uninstallPath" } ) | ForEach-Object { Get-ItemProperty $_.PSPath } | Where-Object { $_.DisplayName -and !$_.SystemComponent -and !$_.ReleaseType -and !$_.ParentKeyName -and ($_.UninstallString -or $_.NoRemove) } | Sort-Object DisplayName | Select-Object DisplayName } else { "You are running 32-bit Powershell on 64-bit system. Please run 64-bit Powershell instead." | Write-Host -ForegroundColor Red }