50% OFF!!!

Wednesday, September 1, 2010

C# | check if program/application is installed

I searched for a code that getting the list of installed application/programs on my windows pc, but the result wat not satisfying.
I saw that the list of installed programs that i find is NOT like the "Add-Remove Programs" list!!!
The solution is to search for 3 places in registry:
1. SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall inside CurrentUser
2. SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall inside LocalMachine
3. SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall in LocalMachine
And this is my solution...

The Code:
public static bool IsApplictionInstalled(string p_name)
{
    string displayName;
    RegistryKey key;

    // search in: CurrentUser
    key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
    foreach (String keyName in key.GetSubKeyNames())
    {
        RegistryKey subkey = key.OpenSubKey(keyName);
        displayName = subkey.GetValue("DisplayName") as string;
        if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)
        {
            return true;
        }
    }

    // search in: LocalMachine_32
    key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
    foreach (String keyName in key.GetSubKeyNames())
    {
        RegistryKey subkey = key.OpenSubKey(keyName);
        displayName = subkey.GetValue("DisplayName") as string;
        if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)
        {
            return true;
        }
    }

    // search in: LocalMachine_64
    key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
    foreach (String keyName in key.GetSubKeyNames())
    {
        RegistryKey subkey = key.OpenSubKey(keyName);
        displayName = subkey.GetValue("DisplayName") as string;
        if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)
        {
            return true;
        }
    }

    // NOT FOUND
    return false;
}

This is great for searching for installed / uninstall programs.
I would like for some comments...

35 comments:

  1. great code.
    It is good for 32bit and also for 64bit operation system windows.

    I tested it on Windows Vista 64 and it's work good.

    ReplyDelete
  2. Thank you for your code!!


    I suggest disposing the keys properly as well as checking whether OpenSubKey returned != null

    ReplyDelete
  3. thank's kevin, here is updated code:


    public static bool IsApplictionInstalled(string p_name)
    {
        string keyName;

        // search in: CurrentUser
        keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
        if (ExistsInSubKey(Registry.CurrentUser, keyName, "DisplayName", p_name) == true)
        {
            return true;
        }

        // search in: LocalMachine_32
        keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
        if (ExistsInSubKey(Registry.LocalMachine, keyName, "DisplayName", p_name) == true)
        {
            return true;
        }

        // search in: LocalMachine_64
        keyName = @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
        if (ExistsInSubKey(Registry.LocalMachine, keyName, "DisplayName", p_name) == true)
        {
            return true;
        }

        return false;
    }

    private static bool ExistsInSubKey(RegistryKey p_root, string p_subKeyName, string p_attributeName, string p_name)
    {
        RegistryKey subkey;
        string displayName;

        using (RegistryKey key = p_root.OpenSubKey(p_subKeyName))
        {
            if (key != null)
            {
                foreach (string kn in key.GetSubKeyNames())
                {
                    using (subkey = key.OpenSubKey(kn))
                    {
                        displayName = subkey.GetValue(p_attributeName) as string;
                        if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)
                        {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    ReplyDelete
    Replies
    1. where we want to put this code then work .....



      Delete
  4. Hi Great code but you are passing in the program name to check it is installed but where are you getting this from?

    ReplyDelete
  5. You should know the name of the program that you want to uninstall.

    If you know only part of program's name, replace the "EQUAL" lines:
    if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)

    with the following one:
    if (displayName.Contains(displayName) == true)

    BUT, make sure that what it find - matches with your program.

    ReplyDelete
    Replies
    1. Great! I was looking for it all over!
      Now, hay can I return the full display name?

      Delete
    2. displayName contains displayName? How could it not? I think this will give a false positive. Instead of "if (displayName.Contains(displayName) == true)", you will need something like "if (displayName.Contains(p_name) == true)". However you need to check that displayName is not null first.

      Delete
  6. ah right, i want to get all programs installed on the PC. I assumed that you were trying to get all programs that were installed on the PC as displayed in the add/remove programs.

    ReplyDelete
  7. This method check if a given application is installed or NoT.

    so, you need to change the above method:
    1. Create and init empty LIST (List)
    2. remove all comparison IF statements.
    3. instead of "return", store the displayName in a list.
    4. return the list in the end of the method. (and of course change method signature to return List)

    hope i could help...

    ReplyDelete
  8. Is it possible to get the same code in python?

    ReplyDelete
  9. Hi Rahul, sure you can!

    I'm not fimiliar with Pyton too much,
    but all you have to do is to check the registry enteries:

    1. SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall inside CurrentUser
    2. SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall inside LocalMachine
    3. SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall in LocalMachine

    if there is a key named "DisplayName" which contains your application name.

    hope it helps,
    mdb-blog

    ReplyDelete
  10. Hello, I am looking for a code that does it on a remote computer. Do you have any idea, how to do it?

    Thanks,
    Kgb

    ReplyDelete
  11. Can u implement a code that upload the log on email or FTP. Will be awesome if u could do that!

    ReplyDelete
  12. What do you mean by "the log"?
    You want a code for doing what? upload file to FTP? send file through EMAIL?

    please describe yourself,
    MDB-Blog.

    ReplyDelete
  13. I used your example on my windows 7 PC, but made the prog search in the LocalMachine_32 part only. Yet it only gives the subkeys from the Wow6432Node uninstall section.

    The strange thing is, that with Console.Writeline(subkey.name); the prog is showing the keypath SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall but attached with the subkeys of the SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall section.
    It somehow mixes them up and can't read the LocalMachine_32 part on my Win7 PC.

    e.g. it gives
    SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Identity Card
    but this entry only exists in SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall and not in SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

    ReplyDelete
  14. I found out the problem is the inbuild registry virtualization on vista and win7, which forbids x86 programs to get access to the x64 part of the registry and redirects every access to the Wow6432Node subkey.

    Only via a P\Invoke of RegOpenKeyExW, RegEnumKeyW and RegQueryValueEx i got my prog to bypass this virtualization crap, while keeping the .NET 3.5 compatibility. (.NET 4.0 is said to have an easy access already inbuild, btw)

    ReplyDelete
  15. I agree with anonymous from 2011-02-02. MDB-Blog, I think you have it backwards.'

    On a 64-bit machine, SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall actually shows the 64-bit registry hive. Thus, to know which 32-bit applications are installed, you must check SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall.

    So on a 32-bit machine, you only need to check SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, but on a 64-bit machine you must ALSO check SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall.

    ReplyDelete
  16. I meant to add this link that shows what happens: http://msdn.microsoft.com/en-us/library/aa390789(v=VS.85).aspx

    ReplyDelete
  17. I haven't gone through all the comments, but the basic version of the code for VB.NET is:


    Public Shared Function IsApplictionInstalled(ByVal p_name As String) As Boolean

    Dim keyName As String

    '--search CurrentUser
    keyName = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" '@????

    If ExistsInSubKey(Registry.CurrentUser, keyName, "DisplayName", p_name) = True Then
    Return True
    Exit Function
    End If

    '--search LocalMachine 32bit
    keyName = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
    If (ExistsInSubKey(Registry.LocalMachine, keyName, "DisplayName", p_name) = True) Then
    Return True
    Exit Function
    End If
    '--search LocalMachine 64bit
    keyName = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
    If (ExistsInSubKey(Registry.LocalMachine, keyName, "DisplayName", p_name) = True) Then
    Return True
    Exit Function
    End If

    Return False

    End Function



    Public Shared Function ExistsInSubKey(ByVal p_root As RegistryKey, ByVal p_subKeyName As String, ByVal p_attributeName As String, ByVal p_name As String) As Boolean

    Dim SubKey As RegistryKey
    Dim displayName As String = ""
    Dim keyName As String = ""

    Using key As RegistryKey = p_root.OpenSubKey(p_subKeyName)

    If (Not key Is Nothing) Then
    For Each keyName In key.GetSubKeyNames()
    SubKey = key.OpenSubKey(keyName)
    If Not SubKey.GetValue(p_attributeName) Is Nothing Then
    displayName = SubKey.GetValue(p_attributeName).ToString
    If InStr(displayName, p_name) > 0 Then
    Return True
    Exit Function
    End If

    End If

    Next

    End If

    End Using

    Return False

    End Function

    ReplyDelete
  18. I want to the only programs installed on your computer. I do not want to do a windows update and driver installed. I want to do my development.

    ReplyDelete
  19. Awesome, thanks a lot for sharing, all other infos I found were missing the third key Wow6432Node !! Big thanks :-)

    ReplyDelete
  20. write if such thing could also be find out using pure java.
    till yet i have found no java site providing this thing.
    it has now become a challenge for them also && for you guys also.
    waiting for the reply.......

    ReplyDelete
  21. Can i get the path of the installed program? i.e. in which drive/folder the program is residing with full path?

    ReplyDelete
    Replies
    1. you will find, in the same registry folder, a key called:
      InstallLocation

      and if not, u can try use:
      UninstallString

      Delete
  22. How can I get the particular application size and its corresponding icon..?

    ReplyDelete
    Replies
    1. you will find, in the same registry folder, a key called:
      DisplayName

      (more info: http://msdn.microsoft.com/en-us/library/windows/desktop/aa372105(v=vs.85).aspx)

      Delete
  23. This didn't work from me when I installed my software via an MSI. I added a check for another registry key that worked for me:

    public static bool IsApplicationInstalled(string p_name)
    {
    string keyName;

    // search in: CurrentUser
    keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
    if (ExistsInSubKey(Registry.CurrentUser, keyName, "DisplayName", p_name) == true)
    {
    return true;
    }

    // search in: LocalMachine_32
    keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
    if (ExistsInSubKey(Registry.LocalMachine, keyName, "DisplayName", p_name) == true)
    {
    return true;
    }

    // search in: LocalMachine_64
    keyName = @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
    if (ExistsInSubKey(Registry.LocalMachine, keyName, "DisplayName", p_name) == true)
    {
    return true;
    }

    // search in: LocalMachine_64
    keyName = @"SOFTWARE\Classes\Installer\Products";
    if (ExistsInSubKey(Registry.LocalMachine, keyName, "ProductName", p_name) == true)
    {
    return true;
    }

    return false;
    }

    private static bool ExistsInSubKey(RegistryKey p_root, string p_subKeyName, string p_attributeName, string p_name)
    {
    RegistryKey subkey;
    string displayName;

    using (RegistryKey key = p_root.OpenSubKey(p_subKeyName))
    {
    if (key != null)
    {
    foreach (string kn in key.GetSubKeyNames())
    {
    using (subkey = key.OpenSubKey(kn))
    {
    displayName = subkey.GetValue(p_attributeName) as string;
    if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)
    {
    return true;
    }
    }
    }
    }
    }
    return false;
    }

    ReplyDelete
  24. Hey, thanx for the great solution. It is working fine for me but only for HKEY_LM\SOFTWARE\Wow6432Node keys and it is not displaying results for HKEY_LM\SOFTWARE\Microsoft...\Uninstall keys. Any solution? I am using 64bit Win 8.1 and 3.5 .Net Framework.

    ReplyDelete
  25. Mdb Blog: C >>>>> Download Now

    >>>>> Download Full

    Mdb Blog: C >>>>> Download LINK

    >>>>> Download Now

    Mdb Blog: C >>>>> Download Full

    >>>>> Download LINK

    ReplyDelete