吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2132|回复: 11
收起左侧

[Python 转载] Python获取计算机已安装软件的软件名列表

[复制链接]
糊涂虫晓晓 发表于 2022-5-19 09:30
从网上和站内找了好久,没找到正儿八经的获取已安装软件列表的好代码,只能自己动手做一个。


前提:1、已安装软件,是下一步下一步下一步那种安装到电脑上的,什么绿化版 、绿色版、单文件都不算在其内。
2、本编程纯属我自己这个python菜鸟仿照网上大神VB.net做的。
3、只获取了软件名列表,不获取版本,换言之,软件名一样版本不一样的,也在去重范围内,只会留一个。(所以和你卸载程序里的数量应该相差个位数)
4、本程序在去更新时会略有瑕疵,望大神有现成的完整好代码能在回复区贴出来。(C#和Python都可,其他的我就看不懂了,可以给其他人看)
5、从最后的with open可以看出我把获取的列表存在D:\GetSoftware.txt里了,大家运行完一遍可以去那里找找看。
废话不多说了,直接上代码,菜鸟可以用来学习,大神修改作为他用都可。


[Python] 纯文本查看 复制代码
#encoding:utf-8
import winreg
import re
def get_ParentKeyName(next_keyname):
    StdUninstallKey=r'Software\Microsoft\Windows\CurrentVersion\Uninstall'
    key_path = StdUninstallKey + '\\' + next_keyname
    try:
        final_keypath = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key_path)
        ParentKeyName = winreg.QueryValueEx(final_keypath, 'ParentKeyName')
        return ParentKeyName[0]
        #print(ParentKeyName[0])
    except:
        #print("出错了")
        pass
def GetInstallerKeyNameFromGuid(GuidName):
    list01=GuidName.replace("{","").replace("}","").split("-")
    list02=[]
    for i in range(3):
        list02.append(list01[i][::-1])
    for z in range(3,5):
        for j in range(0,len(list01[z][1::2])):
            list02.append(list01[z][1::2][j])
            list02.append(list01[z][0::2][j])
        #print(list02)
    return ''.join(list02)

def get_localsoft(key,zhucebiao):
    ClassesKey = r'Software\Classes\Installer\Products'
    for num in range(0,winreg.QueryInfoKey(key)[0]):
        SystemComponent = 0
        next_keyname=winreg.EnumKey(key,num) #最后一级路径
        key_path=zhucebiao+'\\'+next_keyname
        final_keypath=winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,key_path)
        try:
            SystemComponent,REG_SZ=winreg.QueryValueEx(final_keypath,'SystemComponent')
        except WindowsError:
            pass
        if SystemComponent != 1:
            for i in range(0,winreg.QueryInfoKey(final_keypath)[1]):
                WindowsInstaller=0
                try:
                    WindowsInstaller, REG_SZ = winreg.QueryValueEx(final_keypath, 'WindowsInstaller')
                    #print(type(WindowsInstaller))
                except WindowsError:
                    pass
                if WindowsInstaller != 1:
                    ReleaseType=""
                    #ParentKeyName=""
                    try:
                        ReleaseType, REG_SZ = winreg.QueryValueEx(final_keypath, 'ReleaseType')
                        #ParentKeyName, REG_SZ = winreg.QueryValueEx(final_keypath, 'ParentKeyName')
                    except WindowsError:
                        pass
                    #if(re.match(r'KB[0-9]{6}$',next_keyname) is None or not ReleaseType=="Security Update" or not ReleaseType=="Update Rollup" or not ReleaseType=="Hotfix" or ParentKeyName):
                    if re.search(r'KB[0-9]{6}$',next_keyname) or ReleaseType == "Security Update" or ReleaseType == "Update Rollup" or ReleaseType == "Hotfix" or get_ParentKeyName(next_keyname):
                        pass
                    else:
                        UninstallStringExists=False
                        DisplayName=""
                        for i in range(0, winreg.QueryInfoKey(final_keypath)[1]):
                            zijian = winreg.EnumValue(final_keypath, i)[0]
                            if zijian=='UninstallString':
                                UninstallStringExists = True
                                break
                        if UninstallStringExists == True:
                            try:
                                DisplayName, REG_SZ = winreg.QueryValueEx(final_keypath, 'DisplayName')
                            except WindowsError:
                                pass
                            softname=str(DisplayName)
                            if softname and not softname in ExistingProgramList:
                                ExistingProgramList.append(softname)
                else:
                    Name=""
                    MsiKeyName=GetInstallerKeyNameFromGuid(next_keyname)
                    Class_path = ClassesKey + '\\' + MsiKeyName
                    try:
                        Class_keypath = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, Class_path)
                        Name, REG_SZ = winreg.QueryValueEx(Class_keypath, 'ProductName')
                    except WindowsError:
                        pass
                    if Name and not Name in ExistingProgramList:
                        ExistingProgramList.append(Name)
def get_usersoft(key,zhucebiao):
    ClassesKey = r'Software\Classes\Installer\Products'
    for num in range(0,winreg.QueryInfoKey(key)[0]):
        SystemComponent = 0
        next_keyname=winreg.EnumKey(key,num) #最后一级路径
        key_path=zhucebiao+'\\'+next_keyname
        final_keypath=winreg.OpenKey(winreg.HKEY_USERS,key_path)
        try:
            SystemComponent,REG_SZ=winreg.QueryValueEx(final_keypath,'SystemComponent')
        except WindowsError:
            pass
        if SystemComponent != 1:
            for i in range(0,winreg.QueryInfoKey(final_keypath)[1]):
                WindowsInstaller=0
                try:
                    WindowsInstaller, REG_SZ = winreg.QueryValueEx(final_keypath, 'WindowsInstaller')
                    #print(type(WindowsInstaller))
                except WindowsError:
                    pass
                if WindowsInstaller != 1:
                    ReleaseType=""
                    ParentKeyName=""
                    try:
                        ReleaseType, REG_SZ = winreg.QueryValueEx(final_keypath, 'ReleaseType')
                        ParentKeyName, REG_SZ = winreg.QueryValueEx(final_keypath, 'ParentKeyName')
                    except WindowsError:
                        pass
                    #if re.search(r'KB[0-9]{6}$',next_keyname) or not ReleaseType=="Security Update" or not ReleaseType=="Update Rollup" or not ReleaseType=="Hotfix" or ParentKeyName or not ReleaseType=="Update":
                    if re.search(r'KB[0-9]{6}$',next_keyname) or ReleaseType == "Security Update" or ReleaseType == "Update Rollup" or ReleaseType == "Hotfix" or get_ParentKeyName(next_keyname):
                        pass
                    else:
                        UninstallStringExists=False
                        DisplayName=""
                        for i in range(0, winreg.QueryInfoKey(final_keypath)[1]):
                            zijian = winreg.EnumValue(final_keypath, i)[0]
                            if zijian=='UninstallString':
                                UninstallStringExists = True
                                break
                        if UninstallStringExists == True:
                            try:
                                DisplayName, REG_SZ = winreg.QueryValueEx(final_keypath, 'DisplayName')
                            except WindowsError:
                                pass
                            softname=str(DisplayName)
                            if softname and not softname in ExistingProgramList:
                                ExistingProgramList.append(softname)
                else:
                    Name=""
                    MsiKeyName=GetInstallerKeyNameFromGuid(next_keyname)
                    Class_path = ClassesKey + '\\' + next_keyname
                    try:
                        Class_keypath = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, Class_path)
                        Name, REG_SZ = winreg.QueryValueEx(final_keypath, 'ProductName')
                    except WindowsError:
                        pass
                    if Name and not Name in ExistingProgramList:
                        ExistingProgramList.append(Name)


def user_softget(CuInstallKey):
    for usernum in range(0, winreg.QueryInfoKey(winreg.HKEY_USERS)[0]):

        SystemComponent = 0
        UserSid = winreg.EnumKey(winreg.HKEY_USERS, usernum)  # 第一级路径
        # print(UserSid)
        key_path01 = UserSid + '\\' + CuInstallKey
        try:
            product_path = winreg.OpenKey(winreg.HKEY_USERS, key_path01)
        except:
            continue
        for product_num in range(0, winreg.QueryInfoKey(product_path)[0]):
            ProductFound = False
            CuProductGuid = str(winreg.EnumKey(product_path, product_num))
            key_path02 = r'Software\Microsoft\Windows\CurrentVersion\Installer\UserData'
            userdata_path = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key_path02)
            for userdata_num in range(0, winreg.QueryInfoKey(userdata_path)[0]):
                UserDataKeyName = winreg.EnumKey(userdata_path, userdata_num)
                if UserDataKeyName != "S-1-5-18":
                    ProductsKey = key_path02 + "\\" + UserDataKeyName + "\\Products"
                    try:
                        pro_path = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, ProductsKey)
                    except:
                        continue
                    for a in range(0, winreg.QueryInfoKey(pro_path)[0]):
                        LmProductGuid = str(winreg.EnumKey(pro_path, a))
                        if LmProductGuid == CuProductGuid:
                            SystemComponent = 0
                            UserDataProgramKey = ProductsKey + "\\" + LmProductGuid + "\\InstallProperties"
                            UserDataProgramKey_path = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, UserDataProgramKey)
                            try:
                                SystemComponent, REG_SZ = winreg.QueryValueEx(UserDataProgramKey_path,
                                                                              'SystemComponent')
                            except:
                                pass
                            if SystemComponent != 1:
                                Name = ""
                                ProName = key_path01 + "\\" + CuProductGuid
                                ProName_path = winreg.OpenKey(winreg.HKEY_USERS, ProName)
                                try:
                                    Name, REG_SZ = winreg.QueryValueEx(ProName_path, 'ProductName')
                                except:
                                    pass
                                if Name and not Name in ExistingProgramList:
                                    ExistingProgramList.append(Name)

if __name__ == "__main__":
    #Wow64UninstallKey=r'SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
    #ClassesKey=r'Software\Classes\Installer\Products'
    #StdUninstallKey=r'Software\Microsoft\Windows\CurrentVersion\Uninstall'
    CuUnInstallKey=r'Software\Microsoft\Windows\CurrentVersion\Uninstall'
    CuInstallKey = r'Software\Microsoft\Installer\Products'
    ExistingProgramList = []
    list001=[r'SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall',r'Software\Microsoft\Windows\CurrentVersion\Uninstall']
    for i in list001:
        key = winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, i)
        get_localsoft(key,i)
    #key = winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, StdUninstallKey)
    #get_localsoft(key, StdUninstallKey)
    for usernum in range(0, winreg.QueryInfoKey(winreg.HKEY_USERS)[0]):
        UserSid = winreg.EnumKey(winreg.HKEY_USERS, usernum)  # 第一级路径
        # print(UserSid)
        key_path01 = UserSid + '\\' + CuUnInstallKey
        try:
            key = winreg.OpenKeyEx(winreg.HKEY_USERS, key_path01)
            get_usersoft(key, key_path01)
        except:
            continue
    user_softget(CuInstallKey)
    ExistingProgramList.sort()
    #print(ExistingProgramList)
    #print("去除重名软件,共{}项".format(len(ExistingProgramList)))
    with open("D:/GetSoftware.txt",'w') as f:
        f.write("去除重名软件,共{}项".format(len(ExistingProgramList)))
        f.write('\n')
        for soft in ExistingProgramList:
            f.write(soft)
            f.write('\n')
    #print(sorted(ExistingProgramList), len(ExistingProgramList))
    #QueryInfoKey(key)返回3元素元组(下一级路径总数,子健的数量,最后修改时间),
    # 当没有下一级路径,第一个元素为0,当有下一级路径,第二个元素为0,最后修改时间为自1601年1月1日以来的100纳秒

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
wda114514 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

lsyh1688 发表于 2022-5-19 12:22
运行了一下,报错
Traceback (most recent call last):
  File "E:/Pythondata/列出电脑软件.py", line 228, in <module>
    with open("D:/GetSoftware.txt", 'w') as f:
PermissionError: [Errno 13] Permission denied: 'D:/GetSoftware.txt'
修改228行为:
228    with open("D:/list/GetSoftware.txt", 'w') as f:

再次运行,报错232行,如下
Traceback (most recent call last):
  File "E:/Pythondata/列出电脑软件.py", line 232, in <module>
    f.write(soft)
UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position 7: illegal multibyte sequence

求教如何修改?
 楼主| 糊涂虫晓晓 发表于 2022-5-22 21:58
lsyh1688 发表于 2022-5-19 12:22
运行了一下,报错
Traceback (most recent call last):
  File "E:/Pythondata/列出电脑软件.py", line 2 ...

你这个错误,我要是遇到的话,解决思路是这样的:第一,print列表ExistingProgramList试一下,看看正不正常,不正常说明获取软件列表就出了问题,里面是乱码,就在存入字符串的时候就把字符串的编码调一下,这里可以设断点可以print,就能看出了,第二,如果列表输入没问题,说明文件打开写入有问题,在重新建一个py文件,单独写入字符串或者自建一个列表写入试试,这两步做完应该就没问题了。
AmadeusKurisu 发表于 2022-5-19 11:55
Dark_Forest 发表于 2022-5-20 14:34
lsyh1688 发表于 2022-5-19 12:22
运行了一下,报错
Traceback (most recent call last):
  File "E:/Pythondata/列出电脑软件.py", line 2 ...

编码问题
lsyh1688 发表于 2022-5-20 15:34

问题在哪里呢?
wda114514 发表于 2022-5-20 15:35
感谢分享
 楼主| 糊涂虫晓晓 发表于 2022-5-22 21:51
AmadeusKurisu 发表于 2022-5-19 11:55
这东西控制面板不能看吗?

这是我们直属领导的要求,让我做个东西,分发下去,让他们每周运行一次,获取他们都安装了什么软件,有没有游戏什么,本来还要弄个游戏名的池子,进行判断,懒得弄了,一步一步来
 楼主| 糊涂虫晓晓 发表于 2022-5-22 21:54
lsyh1688 发表于 2022-5-19 12:22
运行了一下,报错
Traceback (most recent call last):
  File "E:/Pythondata/列出电脑软件.py", line 2 ...

你把编码改为GBK试试,我是用的Pycharm,但是因为要连sqlserver数据库写入中文,所以把Pycharm的全局变量改为了GBK也可以是CP936,两个是一样的东西,你改改试试。
lsyh1688 发表于 2022-5-22 22:36
本帖最后由 lsyh1688 于 2022-5-22 22:38 编辑
糊涂虫晓晓 发表于 2022-5-22 21:51
这是我们直属领导的要求,让我做个东西,分发下去,让他们每周运行一次,获取他们都安装了什么软件,有没 ...

看到这个原因,感觉领导太......吧。

前一段网上热议的,离职分析监控系统;下班前在群中发每个人手机各程序用电量信息。感觉这样的领导毕竟是少数。

没想到这又冒出一个。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 06:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表