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

如何用Python获取Windows、Linux系统已装应用及版本?求跨平台脚本实现方案

Absolutely! You can totally pull off retrieving installed apps and their version details on both Windows and Linux with Python. Let's break this down step by step—first covering each OS-specific approach, then combining them into a cross-platform script.


Windows 平台实现方案

Most desktop apps installed on Windows leave entries in the Windows Registry, specifically under the Uninstall keys. We can use Python's built-in winreg module to access these entries and extract app names and versions.

核心思路

We'll check two registry paths to cover both 64-bit and 32-bit apps:

  • SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall (for 64-bit apps)
  • SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall (for 32-bit apps running on 64-bit Windows)

代码实现

import winreg

def get_windows_apps():
    apps = []
    # 定义要查询的注册表路径
    registry_paths = [
        r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
        r"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
    ]
    
    for path in registry_paths:
        try:
            # 打开本地机器的注册表键
            with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path) as root_key:
                # 获取子键数量,遍历所有子键
                subkey_count = winreg.QueryInfoKey(root_key)[0]
                for i in range(subkey_count):
                    try:
                        subkey_name = winreg.EnumKey(root_key, i)
                        with winreg.OpenKey(root_key, subkey_name) as app_key:
                            # 读取应用名称,跳过无名称的项
                            try:
                                app_name = winreg.QueryValueEx(app_key, "DisplayName")[0]
                            except FileNotFoundError:
                                continue
                            
                            # 读取版本号,无版本则标记为Unknown
                            try:
                                app_version = winreg.QueryValueEx(app_key, "DisplayVersion")[0]
                            except FileNotFoundError:
                                app_version = "Unknown"
                            
                            apps.append({"name": app_name, "version": app_version})
                    except (OSError, FileNotFoundError):
                        # 跳过无法访问的子键(比如权限不足)
                        continue
        except PermissionError:
            print("⚠️ 提示:需要管理员权限才能读取全部应用信息,部分系统应用可能无法获取")
            continue
    
    # 去重,避免32/64位重复项
    return list({app["name"]: app for app in apps}.values())

Linux 平台实现方案

Linux doesn't have a centralized registry like Windows—installed apps are managed by package managers (dpkg, rpm, flatpak, snap, etc.). We'll detect which package managers are available, run their list commands, and parse the output.

核心思路

  • Check for common package managers (dpkg for Debian/Ubuntu, rpm for RHEL/CentOS, flatpak/snap for universal apps)
  • Run the appropriate command to get app names and versions
  • Parse the command output into a structured list

代码实现

import subprocess

def get_linux_apps():
    apps = []
    # 定义包管理器的命令、参数和解析规则
    package_managers = [
        # Debian/Ubuntu系:dpkg-query
        ("dpkg-query", ["-W", "-f=${Package}\t${Version}\n"], lambda line: line.split('\t')),
        # RHEL/CentOS/Fedora系:rpm
        ("rpm", ["-qa", "--queryformat=%{NAME}\t%{VERSION}\n"], lambda line: line.split('\t')),
        # Flatpak通用应用
        ("flatpak", ["list", "--columns=name,version"], lambda line: line.split('\t')),
        # Snap通用应用
        ("snap", ["list"], lambda line: line.split()[0:2])
    ]
    
    for pm_cmd, pm_args, parser in package_managers:
        try:
            # 先检查包管理器是否存在
            subprocess.run([pm_cmd, "--version"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            # 执行获取列表的命令
            result = subprocess.run([pm_cmd] + pm_args, capture_output=True, text=True, check=True)
            
            # 解析输出内容
            for line in result.stdout.split('\n'):
                line = line.strip()
                # 跳过表头和空行
                if not line or line.startswith(("Name", "Package", "Command")):
                    continue
                
                parts = parser(line)
                if len(parts) >= 2:
                    app_name = parts[0].strip()
                    app_version = parts[1].strip()
                    apps.append({"name": app_name, "version": app_version})
        except (subprocess.CalledProcessError, FileNotFoundError):
            # 包管理器不存在或执行失败,跳过
            continue
    
    # 去重,避免同一应用在多个包管理器中重复出现
    return list({app["name"]: app for app in apps}.values())

跨平台整合脚本

Now let's combine the two functions into a single script that automatically detects the OS and runs the appropriate logic.

import os

def get_windows_apps():
    import winreg
    apps = []
    registry_paths = [
        r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
        r"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
    ]
    
    for path in registry_paths:
        try:
            with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path) as root_key:
                subkey_count = winreg.QueryInfoKey(root_key)[0]
                for i in range(subkey_count):
                    try:
                        subkey_name = winreg.EnumKey(root_key, i)
                        with winreg.OpenKey(root_key, subkey_name) as app_key:
                            try:
                                app_name = winreg.QueryValueEx(app_key, "DisplayName")[0]
                            except FileNotFoundError:
                                continue
                            
                            try:
                                app_version = winreg.QueryValueEx(app_key, "DisplayVersion")[0]
                            except FileNotFoundError:
                                app_version = "Unknown"
                            
                            apps.append({"name": app_name, "version": app_version})
                    except (OSError, FileNotFoundError):
                        continue
        except PermissionError:
            print("⚠️ 提示:需要管理员权限才能读取全部应用信息,部分系统应用可能无法获取")
            continue
    
    return list({app["name"]: app for app in apps}.values())

def get_linux_apps():
    import subprocess
    apps = []
    package_managers = [
        ("dpkg-query", ["-W", "-f=${Package}\t${Version}\n"], lambda line: line.split('\t')),
        ("rpm", ["-qa", "--queryformat=%{NAME}\t%{VERSION}\n"], lambda line: line.split('\t')),
        ("flatpak", ["list", "--columns=name,version"], lambda line: line.split('\t')),
        ("snap", ["list"], lambda line: line.split()[0:2])
    ]
    
    for pm_cmd, pm_args, parser in package_managers:
        try:
            subprocess.run([pm_cmd, "--version"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            result = subprocess.run([pm_cmd] + pm_args, capture_output=True, text=True, check=True)
            
            for line in result.stdout.split('\n'):
                line = line.strip()
                if not line or line.startswith(("Name", "Package", "Command")):
                    continue
                
                parts = parser(line)
                if len(parts) >= 2:
                    app_name = parts[0].strip()
                    app_version = parts[1].strip()
                    apps.append({"name": app_name, "version": app_version})
        except (subprocess.CalledProcessError, FileNotFoundError):
            continue
    
    return list({app["name"]: app for app in apps}.values())

def main():
    print("🔍 正在扫描已安装应用程序...\n")
    if os.name == "nt":
        # Windows系统
        apps = get_windows_apps()
    elif os.name == "posix":
        # Linux/Unix系统
        apps = get_linux_apps()
    else:
        print("❌ 不支持当前操作系统")
        return
    
    print(f"✅ 共检测到 {len(apps)} 个已安装应用:")
    for idx, app in enumerate(apps, 1):
        print(f"{idx}. {app['name']} - 版本: {app['version']}")

if __name__ == "__main__":
    main()

注意事项
  • Windows: Run the script as Administrator to access all registry entries. Green/portable apps that don't write to the registry won't be detected.
  • Linux: Manually compiled apps (installed via make install) aren't tracked by package managers, so they won't show up. The script covers common package managers, but you can add more if you use a niche one.
  • Duplicates: The script uses a dictionary to deduplicate entries, so you won't see the same app listed multiple times.

内容的提问来源于stack exchange,提问作者mad-eye

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:48:58