【问题标题】:List of installed programs已安装程序列表
【发布时间】:2018-11-03 14:50:09
【问题描述】:

我使用寄存器中的搜索和 Win32_Product 类来获取计算机上安装的程序的列表,但它并没有给出所有程序,我见过 C++ 中给出相同结果的程序就像在控制面板的程序和组件中一样。是否有任何适用于 python 的 api 可以给我相同的结果。 这是 c ++ https://www.codeproject.com/Articles/6791/How-to-get-a-list-of-installed-applications 的代码 这就是我使用的: 导入 win32com.client

strComputer = "."
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
objSWbemServices = objWMIService.ConnectServer(strComputer, "root\cimv2")
colItems = objSWbemServices.ExecQuery("Select * from Win32_Product")
for objItem in colItems:

print("Name: ", objItem.Name)

还有注册表:

 aReg = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
                    aKey = OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")
                    for i in range(1024):
                        try:
                            asubkey_name = EnumKey(aKey, i)
                            asubkey = OpenKey(aKey, asubkey_name)
                            val = str(QueryValueEx(asubkey, "DisplayName"))
                            b = "!@#$,01'"
                            for char in b:
                                val = val.replace(char, "")
                            r = len(val)
                            val = str(val[1:r - 2])
                            val2 = str(QueryValueEx(asubkey, "DisplayIcon"))
                            if s.lower() in val.lower():
                                r = len(val2)
                                val2 = str(val2[2:r - 5])
                                # print(val2)
                                subprocess.Popen(val2)
                                break
                            # print(val, val2)
                        except EnvironmentError:
                            continue

【问题讨论】:

  • 并非所有应用程序都需要安装,因此未在操作系统中注册,因此无论您采取何种方法,除了扫描之外,您将无法找到所有内容 EXE 文件的整个 HDD。
  • 确保同时读取SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall 的 32 位和 64 位分支。 FlagsKEY_WOW64_32KEY 显式访问 32 位分支和 KEY_WOW64_64KEY 显式访问 64 位分支。
  • @zett42 这些键不包含完全相同的东西吗?

标签: python winapi pywin32


【解决方案1】:

略微改进的版本,无需 win32con 导入即可工作并检索软件版本和发布者。感谢 Barmak Shemirani 的初步回答 :)

[编辑] 免责声明:本文中的代码已过时。 我已将该代码作为 python 包发布。 使用pip install windows_tools.installed_software安装

用法:

from windows_tools.installed_software import get_installed_software

for software in get_installed_software():
    print(software['name'], software['version'], software['publisher'])

[/编辑]

import winreg

def foo(hive, flag):
    aReg = winreg.ConnectRegistry(None, hive)
    aKey = winreg.OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
                          0, winreg.KEY_READ | flag)

    count_subkey = winreg.QueryInfoKey(aKey)[0]

    software_list = []

    for i in range(count_subkey):
        software = {}
        try:
            asubkey_name = winreg.EnumKey(aKey, i)
            asubkey = winreg.OpenKey(aKey, asubkey_name)
            software['name'] = winreg.QueryValueEx(asubkey, "DisplayName")[0]

            try:
                software['version'] = winreg.QueryValueEx(asubkey, "DisplayVersion")[0]
            except EnvironmentError:
                software['version'] = 'undefined'
            try:
                software['publisher'] = winreg.QueryValueEx(asubkey, "Publisher")[0]
            except EnvironmentError:
                software['publisher'] = 'undefined'
            software_list.append(software)
        except EnvironmentError:
            continue

    return software_list

software_list = foo(winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_32KEY) + foo(winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_64KEY) + foo(winreg.HKEY_CURRENT_USER, 0)

for software in software_list:
    print('Name=%s, Version=%s, Publisher=%s' % (software['name'], software['version'], software['publisher']))
print('Number of installed apps: %s' % len(software_list))

【讨论】:

  • 感谢您的回答,希望有一天我能完成我的项目。
【解决方案2】:

使用 KEY_WOW64_32KEYKEY_WOW64_64KEY 检查 32 位和 64 位注册表。此外,一些安装程序会使用HKEY_CURRENT_USER,尽管后者很少使用。

注意,pywin32 的QueryValueEx 返回一个元组,该元组中的第一个元素包含所需的字符串。 QueryInfoKey 返回一个元组,其第一个元素是子键的总数。

def foo(hive, flag):
    aReg = winreg.ConnectRegistry(None, hive)
    aKey = winreg.OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", 
                          0, win32con.KEY_READ | flag)

    count_subkey = winreg.QueryInfoKey(aKey)[0]
    for i in range(count_subkey):
        try:
            asubkey_name = winreg.EnumKey(aKey, i)
            asubkey = winreg.OpenKey(aKey, asubkey_name)
            val = winreg.QueryValueEx(asubkey, "DisplayName")[0]
            print(val)
        except EnvironmentError:
            continue

foo(win32con.HKEY_LOCAL_MACHINE, win32con.KEY_WOW64_32KEY)
foo(win32con.HKEY_LOCAL_MACHINE, win32con.KEY_WOW64_64KEY)
foo(win32con.HKEY_CURRENT_USER, 0)

【讨论】:

  • 是否有一个选项可以找到允许它们运行的​​所有 exe 模块?我可以获取安装它们的文件夹的名称,但无法获取 exe 模块的确切名称...
  • 不,没有办法可靠地做到这一点。你可以检查"DisplayIcon" 看看它是否是exe文件,它可能指向主应用程序。安装程序需要将 "InstallLocation" 位置放在卸载键中,主 exe(如果有)可以在该文件夹中的任何位置。有些安装程序甚至不遵守规则。
猜你喜欢
  • 2017-05-13
  • 1970-01-01
  • 1970-01-01
  • 2011-09-04
  • 2015-09-17
  • 1970-01-01
  • 2013-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多