@JonB Thanks a lot. Apparently the QFileIconProvider class was removed from PyQt6, but QFileSystemModel can be used instead.
Here's the updated code, it now successfully creates a QIcon for .exe icon paths. On my system there's still some application icon paths that aren't being found by the get_installed_apps_from_registry method, or maybe they just don't exist in the registry, so maybe someone will be able to improve upon this code:
import sys
import os
import winreg
from PyQt6.QtWidgets import QApplication, QComboBox, QMainWindow
from PyQt6.QtGui import QIcon, QFileSystemModel
from PyQt6.QtCore import QSize
def get_installed_apps_from_registry(registry_path):
apps = []
try:
reg_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, registry_path, 0, winreg.KEY_READ)
for i in range(0, winreg.QueryInfoKey(reg_key)[0]):
try:
subkey_name = winreg.EnumKey(reg_key, i)
subkey = winreg.OpenKey(reg_key, subkey_name)
# Retrieve app name
app_name, _ = winreg.QueryValueEx(subkey, "DisplayName")
# Retrieve app icon path
try:
icon_path, _ = winreg.QueryValueEx(subkey, "DisplayIcon")
icon_path = icon_path.split(",")[0].strip() # Clean up icon path
if not os.path.isfile(icon_path):
icon_path = None
except FileNotFoundError:
icon_path = None
# Append app name and icon path to the list
apps.append({"name": app_name, "icon": icon_path})
except EnvironmentError:
continue
finally:
subkey.Close()
except EnvironmentError:
pass
return apps
def list_installed_apps():
registry_paths = [
r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
r"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
]
installed_apps = []
for path in registry_paths:
installed_apps.extend(get_installed_apps_from_registry(path))
# Remove duplicates and sort
unique_apps = {app['name']: app for app in installed_apps if app['name']}
sorted_apps = sorted(unique_apps.values(), key=lambda x: x['name'])
return sorted_apps
class AppComboBox(QMainWindow):
def __init__(self, apps):
super().__init__()
self.setWindowTitle("Installed Applications")
self.setGeometry(100, 100, 400, 100)
# Create QComboBox
self.combo = QComboBox(self)
self.combo.setIconSize(QSize(32, 32))
self.combo.setGeometry(50, 20, 300, 40)
# Initialize QFileSystemModel to fetch icons
self.file_model = QFileSystemModel()
# Add apps to combo box with icons
for app in apps:
icon = self.get_icon(app['icon']) if app['icon'] else QIcon()
self.combo.addItem(icon, app['name'])
def get_icon(self, icon_path):
# Fetches an icon using QFileSystemModel based on file path
if icon_path and os.path.isfile(icon_path):
index = self.file_model.index(icon_path)
return self.file_model.fileIcon(index)
return QIcon() # Return an empty icon if path is invalid
def main():
# Fetch installed applications
apps = list_installed_apps()
# Print program name and icon path
for app in apps:
print(f"Name: {app['name']}")
print(f"Icon Path: {app['icon']}")
print("-" * 40)
# Set up the PyQt6 application
app = QApplication(sys.argv)
window = AppComboBox(apps)
window.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()