You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python打开任意程序?寻求通用解决方案

通用Python打开程序方案及获取已安装程序列表方法

你遇到的这个问题确实很常见——想要一个不用硬编码路径或exe名称的通用方案来打开程序,对吧?我来给你几个实用的解决思路:

一、优先尝试:跨平台调用系统自带的启动命令

这个方法不需要你手动找exe路径或名称,直接借助系统本身的程序查找能力,代码也很简洁:

import subprocess
import platform

def open_program(program_name):
    system = platform.system()
    try:
        if system == 'Windows':
            # Windows下start命令会自动匹配PATH或已注册的应用,支持程序名或友好名称(比如"Google Chrome")
            subprocess.run(['start', '', program_name], shell=True, check=True)
        elif system == 'Darwin':  # macOS系统
            # open -a 后跟应用名称即可,比如"Safari"或"Visual Studio Code"
            subprocess.run(['open', '-a', program_name], check=True)
        elif system == 'Linux':
            # xdg-open 是Linux桌面环境的通用启动命令,支持程序名或.desktop文件名称
            subprocess.run(['xdg-open', program_name], check=True)
        else:
            print(f"暂不支持的操作系统:{system}")
    except subprocess.CalledProcessError:
        print(f"无法打开程序:{program_name},请检查程序是否已安装")

这个方法的优势:

  • 完全不需要硬编码任何路径或exe名称,用户安装新程序后也能直接调用
  • 跨平台兼容Windows/macOS/Linux三大主流系统
  • 支持用程序的友好名称(比如"计算器"而不是calc.exe,"Chrome"而不是chrome.exe)

二、如果需要获取所有已安装程序及exe路径

如果你确实需要遍历用户电脑上的所有已安装程序,不同系统的实现方式不一样,下面是各平台的具体方案:

Windows系统:读取注册表

Windows的已安装程序信息大多存在注册表的两个路径下,我们可以通过winreg模块读取:

import winreg

def get_windows_installed_programs():
    installed_programs = []
    # 系统级安装程序(HKLM)和用户级安装程序(HKCU)的注册表路径
    registry_paths = [
        (winreg.HKEY_LOCAL_MACHINE, r"Software\Microsoft\Windows\CurrentVersion\Uninstall"),
        (winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Uninstall")
    ]
    
    def scan_registry_key(root_key, key_path):
        try:
            with winreg.OpenKey(root_key, key_path) as main_key:
                subkey_count = winreg.QueryInfoKey(main_key)[0]
                for i in range(subkey_count):
                    try:
                        subkey_name = winreg.EnumKey(main_key, i)
                        with winreg.OpenKey(main_key, subkey_name) as sub_key:
                            # 获取程序显示名称
                            display_name = winreg.QueryValueEx(sub_key, "DisplayName")[0]
                            # 尝试获取exe路径:优先从InstallLocation找,其次从UninstallString提取
                            exe_path = None
                            try:
                                install_loc = winreg.QueryValueEx(sub_key, "InstallLocation")[0]
                                # 这里可以进一步扫描安装目录下的exe文件,比如找带程序名称的主exe
                                # 简化处理的话,先记录安装路径
                                exe_path = install_loc
                            except:
                                pass
                            if not exe_path:
                                try:
                                    uninstall_str = winreg.QueryValueEx(sub_key, "UninstallString")[0]
                                    # 卸载字符串通常包含exe路径,比如"C:\xxx\uninstall.exe"
                                    exe_path = uninstall_str.split('"')[1] if '"' in uninstall_str else uninstall_str.split()[0]
                                except:
                                    pass
                            installed_programs.append({
                                "name": display_name,
                                "exe_path": exe_path
                            })
                    except Exception:
                        # 跳过无法读取的子键(比如部分系统程序)
                        continue
        except Exception:
            pass
    
    for root, path in registry_paths:
        scan_registry_key(root, path)
    # 去重并过滤空名称的条目
    return list({prog['name']: prog for prog in installed_programs if prog['name']}.values())

# 使用示例:打印前10个已安装程序
for prog in get_windows_installed_programs()[:10]:
    print(f"程序名称:{prog['name']},路径:{prog['exe_path']}")

macOS系统:扫描应用目录+LaunchServices数据库

macOS的应用大多在/Applications目录下,同时可以通过LaunchServices获取已注册的应用:

import subprocess
import os

def get_macos_installed_programs():
    installed_programs = []
    # 扫描/Applications目录下的.app包
    app_dir = "/Applications"
    for app_name in os.listdir(app_dir):
        if app_name.endswith(".app"):
            app_path = os.path.join(app_dir, app_name)
            installed_programs.append({
                "name": app_name.replace(".app", ""),
                "app_path": app_path
            })
    # 通过lsregister命令获取所有已注册的应用(包括不在/Applications的)
    try:
        result = subprocess.run(
            ['/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister', '-dump'],
            capture_output=True, text=True
        )
        # 解析输出提取应用信息(这里简化处理,提取bundle路径和名称)
        for line in result.stdout.splitlines():
            if "bundle path" in line:
                app_path = line.split("=")[1].strip()
                app_name = os.path.basename(app_path).replace(".app", "")
                installed_programs.append({
                    "name": app_name,
                    "app_path": app_path
                })
    except:
        pass
    # 去重
    return list({prog['name']: prog for prog in installed_programs}.values())

Linux系统:扫描.desktop文件

Linux桌面环境的应用信息通常存储在/usr/share/applications和~/.local/share/applications的.desktop文件中:

import os
import configparser

def get_linux_installed_programs():
    installed_programs = []
    desktop_paths = [
        "/usr/share/applications",
        os.path.expanduser("~/.local/share/applications")
    ]
    
    for path in desktop_paths:
        if not os.path.exists(path):
            continue
        for filename in os.listdir(path):
            if filename.endswith(".desktop"):
                file_path = os.path.join(path, filename)
                config = configparser.ConfigParser()
                try:
                    config.read(file_path)
                    if "Desktop Entry" not in config:
                        continue
                    app_name = config["Desktop Entry"].get("Name", "")
                    exec_path = config["Desktop Entry"].get("Exec", "")
                    # 去掉Exec路径后的参数(比如 %U %F 等)
                    exec_path = exec_path.split()[0] if exec_path else ""
                    if app_name:
                        installed_programs.append({
                            "name": app_name,
                            "exec_path": exec_path
                        })
                except:
                    continue
    # 去重
    return list({prog['name']: prog for prog in installed_programs}.values())

总结

  • 如果只是想打开程序,优先用跨平台调用系统启动命令的方法,这是最简洁通用的方案,用户装新程序后也能直接用
  • 如果必须获取所有已安装程序列表,需要针对不同系统写对应的逻辑,因为各系统的程序存储机制不一样

内容的提问来源于stack exchange,提问作者Rajnish Rajput

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:50:54