3

I use the search in the register and the Win32_Product class to get the list of the programs installed on the computer, but it doesn’t give all the programs, I’ve seen programs in C ++ that give the same results as in the programs and components of the control panel. Is there any api for python that can give me the same result. Here is the code for c ++ https://www.codeproject.com/Articles/6791/How-to-get-a-list-of-installed-applications That's what i use: import win32com.client

strComputer = "."
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
objSWbemServices = objWMIService.ConnectServer(strComputer, "root\cimv2")
colItems = objSWbemServices.ExecQuery("Select * from Win32_Product")
for objItem in colItems:

print("Name: ", objItem.Name)

And whis registry:

 aReg = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
                    aKey = OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")
                    for i in range(1024):
                        try:
                            asubkey_name = EnumKey(aKey, i)
                            asubkey = OpenKey(aKey, asubkey_name)
                            val = str(QueryValueEx(asubkey, "DisplayName"))
                            b = "!@#$,01'"
                            for char in b:
                                val = val.replace(char, "")
                            r = len(val)
                            val = str(val[1:r - 2])
                            val2 = str(QueryValueEx(asubkey, "DisplayIcon"))
                            if s.lower() in val.lower():
                                r = len(val2)
                                val2 = str(val2[2:r - 5])
                                # print(val2)
                                subprocess.Popen(val2)
                                break
                            # print(val, val2)
                        except EnvironmentError:
                            continue
petezurich
  • 9,280
  • 9
  • 43
  • 57
  • 1
    Not all applications require installation and so are not registered with the OS, so no matter what approach you take, you won't be able to find *everything*, short of scanning the entire HDD for EXE files. – Remy Lebeau Nov 03 '18 at 17:44
  • 1
    Make sure to read both 32-bit and 64-bit branches of `SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall`. [Flags](https://learn.microsoft.com/en-us/windows/desktop/SysInfo/registry-key-security-and-access-rights) are `KEY_WOW64_32KEY` to explicitly access the 32-bit branch and `KEY_WOW64_64KEY` to explicitly access the 64-bit branch. – zett42 Nov 03 '18 at 23:04
  • @zett42 don't those keys contain exactly the same thing? – Jabberwocky Nov 06 '18 at 07:03

2 Answers2

12

Slightly improved version that works without win32con import and retrieves software version and publisher. Thanks Barmak Shemirani for his initial answer :)

[EDIT] Disclaimer: The code in this post is outdated. I have published that code as a python package. Install with pip install windows_tools.installed_software

Usage:

from windows_tools.installed_software import get_installed_software

for software in get_installed_software():
    print(software['name'], software['version'], software['publisher'])

[/EDIT]

import winreg

def foo(hive, flag):
    aReg = winreg.ConnectRegistry(None, hive)
    aKey = winreg.OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
                          0, winreg.KEY_READ | flag)

    count_subkey = winreg.QueryInfoKey(aKey)[0]

    software_list = []

    for i in range(count_subkey):
        software = {}
        try:
            asubkey_name = winreg.EnumKey(aKey, i)
            asubkey = winreg.OpenKey(aKey, asubkey_name)
            software['name'] = winreg.QueryValueEx(asubkey, "DisplayName")[0]

            try:
                software['version'] = winreg.QueryValueEx(asubkey, "DisplayVersion")[0]
            except EnvironmentError:
                software['version'] = 'undefined'
            try:
                software['publisher'] = winreg.QueryValueEx(asubkey, "Publisher")[0]
            except EnvironmentError:
                software['publisher'] = 'undefined'
            software_list.append(software)
        except EnvironmentError:
            continue

    return software_list

software_list = foo(winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_32KEY) + foo(winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_64KEY) + foo(winreg.HKEY_CURRENT_USER, 0)

for software in software_list:
    print('Name=%s, Version=%s, Publisher=%s' % (software['name'], software['version'], software['publisher']))
print('Number of installed apps: %s' % len(software_list))
Orsiris de Jong
  • 2,819
  • 1
  • 26
  • 48
3

Check both 32-bit and 64-bit registry using KEY_WOW64_32KEY and KEY_WOW64_64KEY. In addition, some installers will use HKEY_CURRENT_USER, although the latter is rarely used.

Note, pywin32's QueryValueEx returns an tuple, the first element in that tuple contains the required string. QueryInfoKey returns a tuple whose first element is the total number of subkeys.

def foo(hive, flag):
    aReg = winreg.ConnectRegistry(None, hive)
    aKey = winreg.OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", 
                          0, win32con.KEY_READ | flag)

    count_subkey = winreg.QueryInfoKey(aKey)[0]
    for i in range(count_subkey):
        try:
            asubkey_name = winreg.EnumKey(aKey, i)
            asubkey = winreg.OpenKey(aKey, asubkey_name)
            val = winreg.QueryValueEx(asubkey, "DisplayName")[0]
            print(val)
        except EnvironmentError:
            continue

foo(win32con.HKEY_LOCAL_MACHINE, win32con.KEY_WOW64_32KEY)
foo(win32con.HKEY_LOCAL_MACHINE, win32con.KEY_WOW64_64KEY)
foo(win32con.HKEY_CURRENT_USER, 0)
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • Is there an option to find all of their exe modules that will allow them to run? I can get the name of the folder in which they are installed, but I can not get the exact name of the exe module ... – Denis Ladoshkin Nov 04 '18 at 15:28
  • No, there is no way to do that reliably. You can check *"DisplayIcon"* to see if it's exe file, it probably points to the main app. The installer is required to put *"InstallLocation"* location in the uninstall key, the main exe (if any) could be anywhere in that folder. Some installers don't even follow the rule. – Barmak Shemirani Nov 04 '18 at 17:20