Tech Off Thread

5 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

how-to: Print/List installed programs/applications sorted by date

Back to Forum: Tech Off
  • User profile image

    I wanted to copy the list of apps I've installed from control panel add/remove programs (programs and features - uninstall or change a program).

    Of course that doesn't work (in win7). And well since I prefer C# over powershell, here's a quick console app to print the stuff from the registry keys.

            static void Main(string[] args)
                var apps = new List<InstalledApp>();
                using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")) GetInstalledAppValues(key, apps);
                using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")) GetInstalledAppValues(key, apps);
                using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall")) GetInstalledAppValues(key, apps);
                foreach (var a in apps.OrderBy(x => x.InstallDate.HasValue ? x.InstallDate.Value : DateTime.MinValue).ThenBy(x => x.Publisher).ThenBy(x => x.DisplayName))
                    Console.WriteLine("{0,-10} {1,-35} {2} ",a.InstallDate.HasValue ? a.InstallDate.Value.ToShortDateString(): "",a.Publisher,a.DisplayName);
            private static void GetInstalledAppValues(RegistryKey key, List<InstalledApp> apps)
                if (key == null) return;
                foreach (String keyName in key.GetSubKeyNames())
                    var ia = new InstalledApp();
                    ia.DisplayName = (GetValue(key, keyName, "DisplayName") ?? "").Trim();
                    ia.DisplayVersion = GetValue(key, keyName, "DisplayVersion");
                    ia.InstallLocation = GetValue(key, keyName, "InstallLocation");
                    ia.InstallSource = GetValue(key, keyName, "InstallSource");
                    ia.Publisher = GetValue(key, keyName, "Publisher");
                    var dt = GetValue(key, keyName, "InstallDate");
                    if (dt != null)
                        DateTime res;
                        if (!DateTime.TryParseExact(dt, new string[] { "yyyyMMdd", "M/d/yyyy", "d" }, System.Threading.Thread.CurrentThread.CurrentCulture, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out res))
                            DateTime.TryParseExact(dt, new string[] { "yyyyMMdd", "M/d/yyyy", "d" }, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AllowWhiteSpaces,out res);
                        if (res > DateTime.MinValue) ia.InstallDate = res;
                    if (!string.IsNullOrEmpty(ia.DisplayName)) apps.Add(ia);
            private static string GetValue(RegistryKey key, String keyName, string valueName)
                RegistryKey subkey = key.OpenSubKey(keyName);
                return subkey.GetValue(valueName) as string;;
            public class InstalledApp
                public string DisplayName { get; set; }
                public string DisplayVersion { get; set; }
                public DateTime? InstallDate { get; set; }
                public string InstallLocation { get; set; }
                public string InstallSource { get; set; }
                public string Publisher { get; set; }

  • User profile image

    There is probably a bug in the InstallDate parsing. The date values in the registry came in probably 5 different formats and it seems it's not currently parsing all of the formats.

    edit: Looks like the control panel Programs and features is getting the install date of some applications from some other location than registry. But I couldn't see where in process monitor. I think I'm going to just check the possible file from UninstallString for the filedate.

  • User profile image

    There appears to be easier ways to list the programs but they don't list all of the apps the above code does. This code however seems to also list stuff that has been uninstalled already but has left behind some stuff in the uninstall registry.

    Here's the other ways I found:

    powershell one liner, pretty awesome I'd say

    ((gp HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*) + (gp HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*) + (gp HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*)) | Select DisplayName,  DisplayVersion, Publisher, InstallDate, HelpLink, UninstallString | ogv



    Get-WmiObject -Class Win32_Product

    cmd prompt:

    wmic product

    (last two are very slow and incomplete, see notes at:


  • User profile image

    This looks good! I've done something similar by scraping the *.nfo output of MSINFO32 command line but this looks a lot better. 

  • User profile image

    I wasn't happy that some of the apps didn't show the install date, so I'm now parsing the uninstaller string and getting the last write date but some of the apps have the file dates all set to the time the developer made the app instead of the install time...

    There's also a way to query MSI for install date also.

    These changes made the class so big I'm not bothering to paste it here.

    There are also some special cases with the uninstaller string that make the parsing complicated and it would need more testing that I have time for.

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.