Python中替代subprocess调用wmic收集数据的更快方案?
优化Windows已安装产品名称查询速度的Python方案
你当前用subprocess.check_output(['wmic','product','get','name'])慢的核心原因是:wmic product本质是调用WMI的Win32_Product类,这个类在查询时会触发MSI安装包的自我修复检查,加上启动wmic.exe进程的额外开销,导致耗时剧增。
纯Python完全可以优化这个流程,以下是两种高效方案:
方案1:直接读取注册表(推荐,速度提升显著)
绝大多数Windows程序的安装信息会注册到系统注册表中,直接读取注册表无需经过WMI的复杂流程,速度通常在几百毫秒内完成。
代码实现
import winreg def get_installed_programs(): installed = [] # 覆盖64位和32位程序的注册表路径 reg_paths = [ r"Software\Microsoft\Windows\CurrentVersion\Uninstall", r"Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" ] for path in reg_paths: try: # 打开根注册表项 root_key = winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, path, 0, winreg.KEY_READ | winreg.KEY_WOW64_64KEY ) idx = 0 while True: try: # 遍历所有子项 subkey_name = winreg.EnumKey(root_key, idx) subkey = winreg.OpenKey(root_key, subkey_name) # 获取程序显示名称 try: display_name = winreg.QueryValueEx(subkey, "DisplayName")[0] if display_name: installed.append(display_name) except FileNotFoundError: # 部分子项无DisplayName,跳过 pass winreg.CloseKey(subkey) idx += 1 except OSError: # 子项遍历完成,退出循环 break winreg.CloseKey(root_key) except FileNotFoundError: # 32位系统不存在Wow6432Node路径,直接跳过 pass # 去重后返回结果 return list(set(installed)) # 调用示例 for program in get_installed_programs(): print(program)
优势
- 速度极快,远优于WMI调用;
- 覆盖范围更广:包含所有通过标准安装流程注册的软件(而非仅MSI安装的程序);
- 无额外进程启动开销。
方案2:直接调用WMI(比wmic进程快,但仍慢于注册表)
如果必须依赖WMI的Win32_Product类,可以用Python直接连接WMI服务,避免启动wmic.exe的进程开销,但仍会受限于Win32_Product本身的自我修复检查机制,速度提升有限。
代码实现
import win32com.client def get_installed_via_wmi(): wmi_service = win32com.client.GetObject("winmgmts:") products = wmi_service.InstancesOf("Win32_Product") return [prod.Name for prod in products if prod.Name]
总结
优先选择注册表读取方案,能将查询耗时从10-15秒压缩到毫秒级,完全满足你的需求。
内容的提问来源于stack exchange,提问作者Ben Broughton
相关产品推荐
相关产品推荐

