概述
在日常工作和系统管理中,经常需要获取Windows系统中已安装的所有应用程序列表。无论是进行系统审计、软件管理,还是编写自动化脚本,这个功能都非常实用。本文将详细介绍如何使用Python通过访问Windows注册表来获取完整的已安装软件列表。
为什么选择注册表方法
Windows系统中,已安装的应用程序信息主要存储在注册表中。相比于WMI(Windows Management Instrumentation)方法,通过注册表直接获取有以下优势:
更完整的结果:WMI的Win32_Product类通常只能获取到通过Windows Installer安装的程序,而注册表方法可以获取到几乎所有类型的安装程序更高的性能:直接访问注册表比通过WMI查询更快无需管理员权限:可以获取到当前用户安装的程序,而不需要管理员权限
实现原理
Windows系统在以下几个注册表路径中存储了已安装程序的信息:
– 64位系统上的64位程序
HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionUninstall
– 64位系统上的32位程序
HKEY_LOCAL_MACHINESOFTWAREWOW6432NodeMicrosoftWindowsCurrentVersionUninstall
– 当前用户安装的程序
HKEY_CURRENT_USERSOFTWAREMicrosoftWindowsCurrentVersionUninstall
我们的代码将遍历这些路径,读取每个程序的DisplayName值,从而获取完整的已安装软件列表。
完整代码
以下是获取Windows已安装的所有应用程序列表的完整Python代码:
import winreg
import os
def get_installed_software():
# 存储已安装软件名称的集合,用于去重
software_set = set()
# 需要检查的注册表路径
registry_paths = [
# 64位程序 (系统安装)
r"SOFTWAREMicrosoftWindowsCurrentVersionUninstall",
# 32位程序在64位系统上 (系统安装)
r"SOFTWAREWOW6432NodeMicrosoftWindowsCurrentVersionUninstall",
# 当前用户安装的程序
r"SOFTWAREMicrosoftWindowsCurrentVersionUninstall"
]
# 检查不同的根键
hkeys = [winreg.HKEY_LOCAL_MACHINE]
# 如果是当前用户路径,添加HKEY_CURRENT_USER
hkeys.append(winreg.HKEY_CURRENT_USER)
# 遍历所有根键和路径组合
for hkey in hkeys:
for path in registry_paths:
try:
# 打开注册表键
with winreg.OpenKey(hkey, path) as key:
# 获取子键数量
num_subkeys = winreg.QueryInfoKey(key)[0]
# 遍历所有子键
for i in range(num_subkeys):
try:
# 获取子键名称
subkey_name = winreg.EnumKey(key, i)
# 构建完整路径
subkey_path = os.path.join(path, subkey_name)
# 打开子键
with winreg.OpenKey(hkey, subkey_path) as subkey:
try:
# 尝试获取DisplayName值
display_name = winreg.QueryValueEx(subkey, "DisplayName")[0]
# 确保名称不为空且是字符串
if display_name and isinstance(display_name, str):
software_set.add(display_name)
except FileNotFoundError:
# 如果DisplayName不存在,跳过
continue
except Exception:
# 处理子键访问错误
continue
except Exception:
# 处理主键访问错误
continue
# 转换为列表并排序
return sorted(software_set)
# 获取完整的已安装软件列表
software_list = get_installed_software()
# 输出软件数量
print(f"共检测到 {len(software_list)} 个已安装程序:")
print("=" * 50)
# 换行输出每个软件名称
for i, software in enumerate(software_list, 1):
print(f"{i}. {software}")
代码解析
让我们逐步解析这个代码:
1. 导入必要的模块
import winreg
import os
:Python的内置模块,用于访问Windows注册表
winreg
:提供了处理文件和目录路径的函数
os
2. 定义获取已安装软件的函数
def get_installed_software():
# 存储已安装软件名称的集合,用于去重
software_set = set()
# 需要检查的注册表路径
registry_paths = [
# 64位程序 (系统安装)
r"SOFTWAREMicrosoftWindowsCurrentVersionUninstall",
# 32位程序在64位系统上 (系统安装)
r"SOFTWAREWOW6432NodeMicrosoftWindowsCurrentVersionUninstall",
# 当前用户安装的程序
r"SOFTWAREMicrosoftWindowsCurrentVersionUninstall"
]
# 检查不同的根键
hkeys = [winreg.HKEY_LOCAL_MACHINE]
# 如果是当前用户路径,添加HKEY_CURRENT_USER
hkeys.append(winreg.HKEY_CURRENT_USER)
这里我们定义了一个
函数,并初始化了一个集合
get_installed_software()
用于存储软件名称(使用集合可以自动去重)。然后,我们定义了需要检查的注册表路径和根键。
software_set
3. 遍历注册表并获取软件名称
# 遍历所有根键和路径组合
for hkey in hkeys:
for path in registry_paths:
try:
# 打开注册表键
with winreg.OpenKey(hkey, path) as key:
# 获取子键数量
num_subkeys = winreg.QueryInfoKey(key)[0]
# 遍历所有子键
for i in range(num_subkeys):
try:
# 获取子键名称
subkey_name = winreg.EnumKey(key, i)
# 构建完整路径
subkey_path = os.path.join(path, subkey_name)
# 打开子键
with winreg.OpenKey(hkey, subkey_path) as subkey:
try:
# 尝试获取DisplayName值
display_name = winreg.QueryValueEx(subkey, "DisplayName")[0]
# 确保名称不为空且是字符串
if display_name and isinstance(display_name, str):
software_set.add(display_name)
except FileNotFoundError:
# 如果DisplayName不存在,跳过
continue
except Exception:
# 处理子键访问错误
continue
except Exception:
# 处理主键访问错误
continue
这部分代码是核心逻辑,它执行以下操作:
遍历所有根键(HKEY_LOCAL_MACHINE和HKEY_CURRENT_USER)和注册表路径的组合对于每个组合,尝试打开对应的注册表键获取子键数量,并遍历每个子键对于每个子键,尝试获取其DisplayName值如果DisplayName存在且是有效的字符串,则将其添加到software_set集合中使用多层try-except结构来处理可能出现的各种错误,确保程序不会因为某个注册表项的访问问题而中断
4. 返回排序后的软件列表
# 转换为列表并排序
return sorted(software_set)
最后,我们将集合转换为列表并进行排序,以便返回一个有序的软件名称列表。
5. 调用函数并输出结果
# 获取完整的已安装软件列表
software_list = get_installed_software()
# 输出软件数量
print(f"共检测到 {len(software_list)} 个已安装程序:")
print("=" * 50)
# 换行输出每个软件名称
for i, software in enumerate(software_list, 1):
print(f"{i}. {software}")
这部分代码调用
函数获取已安装软件列表,然后输出软件数量和每个软件的名称。我们使用
get_installed_software()
函数来为每个软件添加序号,使输出更加清晰。
enumerate()
使用方法
将上述代码保存为
文件在Windows系统中,使用Python运行该文件:
get_installed_software.py
python get_installed_software.py
程序将输出系统中已安装的所有应用程序列表
可能的扩展和改进
导出到文件:可以将获取到的软件列表导出为CSV、Excel或文本文件,方便保存和分享
# 导出到文本文件
with open('installed_software.txt', 'w', encoding='utf-8') as f:
f.write(f"共检测到 {len(software_list)} 个已安装程序:
")
for i, software in enumerate(software_list, 1):
f.write(f"{i}. {software}
")
获取更多信息:除了软件名称外,还可以获取软件版本、发布者、安装日期等信息
# 尝试获取更多信息
try:
version = winreg.QueryValueEx(subkey, "DisplayVersion")[0]
publisher = winreg.QueryValueEx(subkey, "Publisher")[0]
install_date = winreg.QueryValueEx(subkey, "InstallDate")[0]
except FileNotFoundError:
# 如果这些值不存在,设置默认值
version = "未知"
publisher = "未知"
install_date = "未知"
添加过滤功能:可以根据软件名称、发布者等条件过滤软件列表
# 根据关键词过滤软件列表
keyword = "Microsoft"
filtered_software = [sw for sw in software_list if keyword.lower() in sw.lower()]
图形界面:可以使用Tkinter、PyQt等库为程序添加图形界面,使操作更加直观
总结
通过本文介绍的方法,我们可以使用Python轻松获取Windows系统中已安装的所有应用程序列表。这种方法不仅简单高效,而且能够获取到比WMI方法更完整的结果。无论是用于系统管理、软件审计还是自动化脚本,这个功能都非常实用。
希望本文对您有所帮助,如果您有任何问题或建议,欢迎留言讨论!