Buscar Software Instalado a través del Registro de Windows

Algunas veces es necesario saber que software esta instalado o ha sido instalado en una maquina, por ejemplo al momento de realizar una auditoria informática. Por lo cual tener una pequeña herramienta que nos facilite el trabajo de recolección y organizado de los datos seria bastante útil. Entonces solo queda ponerse manos a la obra, para lo cual primero vamos a crear una aplicación WPF en Visual Studio y luego vamos a agregar la clase DelegateCommand y otra clase llamada ViewModel. Nuestro siguiente paso será crea una función que se ocupe de buscar las llaves en el registro que contengan información de los productos que se encuentra en "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\XXX\Products\" donde XXX varia de maquina en maquina, por lo cual nuestra función se ocupara de entregarnos la llaves bien formadas:
 
        public void LoadRegistryEntries()
        {
            RegistryKey rk = Registry.LocalMachine.OpenSubKey( @"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\" );
            string[ ] names = rk.GetSubKeyNames( );
            foreach ( var item in names )
            {
                RegistryKey sk = rk.OpenSubKey( item ).OpenSubKey( "Products" );
                if ( sk.SubKeyCount > 0 )
                    _listOfRegistryEntries.Add( sk.Name.Substring(19) );
            }
        }
Ya con las llaves de registro obtenidas, crearemos una clase llamada Product que tendrá la siguiente estructura:
 
    public class Product
    {
        public string Name;
        public DateTime InstallationDate;
        public string Version;
        public string Publisher;
        public string InstallationLocation;
    }
Luego crearemos una funcion que nos devuelva una lista de productos en base a una llave de registro dada:
 
       private List<product> GetProductsFromKey(string registryPath)
       {
            List<product> productsOfKey = new List<product>();
            RegistryKey rk = Registry.LocalMachine.OpenSubKey(registryPath);
            String[] names = rk.GetSubKeyNames();
            foreach (var item in names)
            {
                 String[] t = Registry.LocalMachine.OpenSubKey(registryPath).OpenSubKey(item).GetSubKeyNames();
                 if (t.Contains("InstallProperties"))
                 {
                       Product temporalProduct = new Product();
                       temporalProduct.Name = Registry.LocalMachine.OpenSubKey(registryPath).OpenSubKey(item).OpenSubKey      ("InstallProperties").GetValue("DisplayName").ToString();
                        string temporalDate = Registry.LocalMachine.OpenSubKey(registryPath).OpenSubKey(item).OpenSubKey("InstallProperties").GetValue("InstallDate").ToString();
                       int year = int.Parse(temporalDate.Substring(0, 4));
                       int month = int.Parse(temporalDate.Substring(4, 2));
                       int day = int.Parse(temporalDate.Substring(6));
                       temporalProduct.InstallationDate = new DateTime(year, month, day);
                       temporalProduct.Publisher = Registry.LocalMachine.OpenSubKey(registryPath).OpenSubKey(item).OpenSubKey("InstallProperties").GetValue("Publisher").ToString();
                       temporalProduct.Version = Registry.LocalMachine.OpenSubKey(registryPath).OpenSubKey(item).OpenSubKey("InstallProperties").GetValue("DisplayVersion").ToString();
                       temporalProduct.InstallationLocation = Registry.LocalMachine.OpenSubKey(registryPath).OpenSubKey(item).OpenSubKey("InstallProperties").GetValue("InstallLocation").ToString();
                       productsOfKey.Add(temporalProduct);
                 }
            }
            return productsOfKey;
        }
El siguiente paso sera crear nuestro comando que ejecute la búsqueda en el registro que será como sigue:
 
void SearchRegistry_Execute(object parameters)
{
     LoadRegistryEntries( );
     foreach ( var entryList in _listOfRegistryEntries )
     {
           foreach ( var prod in GetProductsFromKey( entryList ) )
           {
                 Products.Add( prod );
           }
     }

     foreach (var item in Products.OrderBy(x => x.Name).Select(x => x.Name))
     {
           NameProducts.Add(item);
     }
}
Por ultimo lo que faltaría seria la interfaz, que como es un poco amplia solo pondré una captura:
 

Suerte!.
Source Code con Metro Style. Para mas referencias de Metro Style vean este post.

Comentarios

Publicar un comentario

Entradas populares de este blog

Conectarse a un Web Service en PHP con WPF

Ejecutar comandos en el CMD de Windows desde C#

Usar Log4Net en un proyecto ASP.NET MVC