如何用Python自动执行系统已安装应用:随机或前3个启动方案
当然可以实现!下面我会一步步帮你改造代码,实现随机选取或选取前3个应用自动执行的功能,同时也会解决原代码里的一些潜在问题。
首先得提一句:你原来用的wmi.Win32_Product()其实不太推荐——这个WMI类会触发Windows Installer的一致性检查,不仅运行慢,还可能意外触发MSI修复操作。更可靠的方式是从系统注册表读取已安装应用信息,我会在代码里兼顾两种方式,但优先推荐注册表方案。
完整实现代码
import wmi import random import subprocess import winreg import os def get_installed_apps_via_registry(): """从注册表获取已安装应用(推荐方式)""" installed_apps = [] # 检查32位和64位系统的注册表路径,以及HKLM/HKCU hives = [(winreg.HKEY_LOCAL_MACHINE, "HKLM"), (winreg.HKEY_CURRENT_USER, "HKCU")] uninstall_paths = [ r"Software\Microsoft\Windows\CurrentVersion\Uninstall", r"Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" ] for hive, hive_name in hives: for path in uninstall_paths: try: root_key = winreg.OpenKey(hive, path) subkey_count = winreg.QueryInfoKey(root_key)[0] for i in range(subkey_count): try: subkey_name = winreg.EnumKey(root_key, i) subkey = winreg.OpenKey(root_key, subkey_name) # 获取应用名称(必填项) display_name = winreg.QueryValueEx(subkey, "DisplayName")[0] # 获取版本和厂商(可选) version = winreg.QueryValueEx(subkey, "DisplayVersion")[0] if "DisplayVersion" in [val[0] for val in winreg.EnumValue(subkey)] else "未知版本" vendor = winreg.QueryValueEx(subkey, "Publisher")[0] if "Publisher" in [val[0] for val in winreg.EnumValue(subkey)] else "未知厂商" installed_apps.append({ "name": display_name, "version": version, "vendor": vendor, "subkey": f"{hive_name}\\{path}\\{subkey_name}" }) except (FileNotFoundError, OSError): # 跳过没有DisplayName的项 continue finally: winreg.CloseKey(subkey) except FileNotFoundError: continue finally: winreg.CloseKey(root_key) return installed_apps def get_installed_apps_via_wmi(): """用WMI Win32_Product获取应用(不推荐,仅兼容原代码)""" w = wmi.WMI() installed_apps = [] for p in w.Win32_Product(): installed_apps.append({ "name": p.Caption, "version": p.Version, "vendor": p.Vendor, "install_location": p.InstallLocation }) return installed_apps def get_app_executable_path(app_info): """根据应用信息查找可执行文件路径""" # 如果是注册表获取的应用,优先从DisplayIcon或InstallLocation找 if "subkey" in app_info: hive_str, subkey_path = app_info["subkey"].split("\\", 1) hive = winreg.HKEY_LOCAL_MACHINE if hive_str == "HKLM" else winreg.HKEY_CURRENT_USER try: subkey = winreg.OpenKey(hive, subkey_path) # 尝试读取DisplayIcon(通常包含exe路径,格式可能是"path.exe,0") try: display_icon = winreg.QueryValueEx(subkey, "DisplayIcon")[0] if "," in display_icon: exe_path = display_icon.split(",")[0].strip('"') else: exe_path = display_icon.strip('"') if os.path.exists(exe_path): return exe_path except FileNotFoundError: pass # 尝试从InstallLocation查找exe文件 try: install_location = winreg.QueryValueEx(subkey, "InstallLocation")[0] if install_location and os.path.exists(install_location): # 遍历目录找包含应用名的exe(简单匹配) for root, _, files in os.walk(install_location): for file in files: if file.endswith(".exe") and app_info["name"].lower() in file.lower(): return os.path.join(root, file) # 只遍历一级目录,避免过慢 break except FileNotFoundError: pass finally: winreg.CloseKey(subkey) # 如果是WMI获取的应用,从InstallLocation查找 elif "install_location" in app_info and app_info["install_location"]: install_location = app_info["install_location"] if os.path.exists(install_location): for root, _, files in os.walk(install_location): for file in files: if file.endswith(".exe") and app_info["name"].lower() in file.lower(): return os.path.join(root, file) break return None def execute_selected_apps(selected_apps): """执行选中的应用""" for app in selected_apps: exe_path = get_app_executable_path(app) if exe_path: print(f"✅ 正在启动 {app['name']}...") # 用subprocess.Popen后台启动应用,不会阻塞脚本 subprocess.Popen(exe_path) else: print(f"❌ 无法找到 {app['name']} 的可执行文件路径") if __name__ == "__main__": # 选择获取应用的方式:推荐用注册表方式 # installed_apps = get_installed_apps_via_wmi() installed_apps = get_installed_apps_via_registry() if not installed_apps: print("未找到已安装的应用") exit() # --- 选取逻辑二选一 --- # 1. 选取前3个应用 selected_apps = installed_apps[:3] if len(installed_apps) >=3 else installed_apps # 2. 随机选取3个应用(如果总数不足3则全选) # selected_apps = random.sample(installed_apps, min(3, len(installed_apps))) print(f"已选中 {len(selected_apps)} 个应用:") for idx, app in enumerate(selected_apps, 1): print(f"{idx}. {app['name']} - {app['version']} ({app['vendor']})") # 执行选中的应用 execute_selected_apps(selected_apps)
关键说明
- 应用列表获取:优先用
get_installed_apps_via_registry(),避免Win32_Product的副作用;如果需要兼容原代码,再用WMI方式。 - 选取逻辑:代码里提供了两种方式,注释掉不需要的即可——前3个直接切片,随机选用
random.sample保证不重复。 - 执行应用:通过
get_app_executable_path函数从注册表的DisplayIcon或安装目录查找可执行文件,解决了Win32_Product没有直接exe路径的问题。 - 启动方式:用
subprocess.Popen后台启动应用,脚本不会被阻塞,可以继续执行其他操作。
内容的提问来源于stack exchange,提问作者JJJ




