1

I am sorry if the title for my question is not apt.

I am a newbie to the programming side and trying to write a console app for getting all the installed apps on the computer from registry.

Here is my code.

class Program
{
    static void Main(string[] args)
    {
        Console.Title = "Windows App Finder - Finds all the installed apps on the station";

        List<AppDetails> apps = new List<AppDetails>();
        apps = GetInstalledApps();
        ListAllApps(apps);
        Console.WriteLine("\nPress any key to exit.");
        Console.ReadLine();
    }

    private static List<AppDetails> GetInstalledApps()
    {
        string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
        AppDetails appInfo = new AppDetails();
        List<AppDetails> apps = new List<AppDetails>();
        using (Microsoft.Win32.RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
        {
            foreach (string subkey_name in key.GetSubKeyNames())
            {
                using (RegistryKey subkey = key.OpenSubKey(subkey_name))
                {

                    appInfo.appName = (string)subkey.GetValue("DisplayName");
                    appInfo.publisher = (string)subkey.GetValue("Publisher");
                    appInfo.appVersion = (string)subkey.GetValue("DisplayVersion");
                    if (appInfo.appName != null )
                    {
                        apps.Add(appInfo);
                    }
                }
            }
        }
            return apps;
    }
    private static void ListAllApps(List<AppDetails> appDetails)
    {
        int i = 0;
        foreach (AppDetails appDetail in appDetails)
        {
            Console.WriteLine(i.ToString() + ". Name: " + appDetail.appName + " Version: " + appDetail.appVersion + " Publisher: " + appDetail.publisher);
            i++;
        }
    }
}

public class AppDetails
{
    public string appName { get; set; }
    public string appVersion {get; set;}
    public string publisher {get;set;}
    public DateTime installDate { get; set; }
}

}

This code returns https://i.sstatic.net/tKtNr.png Single app name repeated multiple times. What is wrong with this piece of code.

Thanks in advance

1 Answer 1

4

You have to instantiate AppDetails appInfo = new AppDetails(); inside your foreach loop, otherwise you will end with same object getting modified and added to the List again and again.

Just move the instantiation to inside your loop.

private static List<AppDetails> GetInstalledApps()
{
    string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
    List<AppDetails> apps = new List<AppDetails>();
    using (Microsoft.Win32.RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
    {
        foreach (string subkey_name in key.GetSubKeyNames())
        {
            using (RegistryKey subkey = key.OpenSubKey(subkey_name))
            {
                AppDetails appInfo = new AppDetails(); //HERE
                appInfo.appName = (string)subkey.GetValue("DisplayName");
                appInfo.publisher = (string)subkey.GetValue("Publisher");
                appInfo.appVersion = (string)subkey.GetValue("DisplayVersion");
                if (appInfo.appName != null)
                {
                    apps.Add(appInfo);
                }
            }
        }
    }
    return apps;
}

Since you are not instantiating the object inside the loop, It is being added to list multiple times, and all the instance in the list points to same reference. Therefore you see the same values returned multiple times. It would be the last value in your iteration.

Sign up to request clarification or add additional context in comments.

3 Comments

'Console.WriteLine(i.ToString() + ". Name: " + appDetail.appName + " Version: " + appDetail.appVersion + " Publisher: " + appDetail.publisher);' This is partially returning the values, i mean in the console i can only see from i = 20. If i give the code 'Console.WriteLine(i.ToString() + ". Name: " + appDetail.appName);' i can see from i = 0; Any guess on what is wrong ?
@Dev05, your screen is probably scrolling and showing you the last records. Scroll up and if that doesn't work then put a simple Console.ReadLine(); after checking value of i in your loop. If (i %10 == 0), then use Console.ReadLine
you are exactly right. The console was only showing only the last records. When i put the Console.Readline as u suggested, i could able to see everything. Thanks again.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.