First of all I just want to say that this is different to every other example of programmatically retrieving a list of installed software that I have seen on the internet. All of the other examples seem to get way too many programs compared to what you would see in Add/Remove Programs in Windows and sometimes miss programs as well - both of these issues are caused by the fact that they rely on just looping through the Uninstall key in the registry or using WMI (which probably does the same thing). Add/Remove Programs looks in several other registry locations as well and I spent a considerable amount of time trying to figure out exactly how it decides which programs to include and which to ignore... but think I have finally got my code to produce an identical list to the list that Add/Remove Programs produces.
So as you have probably guessed, my code does not use WMI, it is all done by just reading registry keys
Retrieves the names (and version) of all installed programs on a computer just like Add/Remove Programs. This was made to work as similarly to Add/Remove programs as possible, so whilst you could actually retrieve more programs (such as system components and drivers), my code should only get the ones that you would normally expect to see.
One advantage my code has over the built in Add/Remove Programs window is that you can run my code against a remote computer just as easily as you can run it on your local computer See below for details.
The DLL contains just one class, InstalledProgram, which has a single Shared method named GetInstalledPrograms which returns a generic List(Of InstalledProgram) and you can specify whether or not you want the returned list to include updates or not. The class also has several properties such as DisplayName, Version and IsUpdate.
I have included an example project with the solution attached to this post that demonstrates how you could use the InstalledProgram class to populate a ListView with all installed programs and their version numbers. If you want to get the list of installed programs from another computer on the network then there is an overloaded version of the GetInstalledPrograms method that accepts a computer name or IP address as an additional parameter. The demo project shows how to use this as well.
Here is a screenshot of the example application included with the attached solution that uses the InstalledProgram class to populate a listview:
As you can see, some items do not have the Version information but this is the same in Add/Remove Programs.
Per User Programs
There is one distinct difference in the way that my code works compared to Add/Remove Programs and that is the way in which user specific programs are handled. When you install a program that just installs for the currently logged on user, such as a ClickOnce app, then Add/Remove Programs will only show you that program if you are logged in as the user that the program was installed for. With my code however, you will see any user specific programs for every user no matter who you are logged on as (as long as the account you are logged in with has the relevant permissions). I made it this way intentionally but let me know if you dont think it should work like that.
I have not really concentrated on this side of things, I just wanted it to retrieve all installed programs and didnt care about windows updates etc but it does get the majority of them, just not all of them. If I get some spare time I'll try and sort that out but at the moment its not a priority
The code seems to work perfectly fine on a 64 bit system if the code is built to target x64 (or AnyCpu) but if you set the code to target x86 then Windows hides/redirects one of the registry keys from the process and that key contains some of the installed programs - the end result being that not all programs may be displayed in this scenario. No such issues on 32 bit operating systems of course.
Version history is now attached to this post
So yeah, try it out and let me know if you find it useful or have any problems/feedback Of course if anyone has any suggestions for improvements to the code as well then feel free to point them out.
Download latest version below