Pyqt 获取windows系统中已安装软件列表
开始之前的基础知识
1. 获取软件列表
在Python的标准库中,_winreg可以操作Windows的注册表。
获取已经安装的软件列表一般是读去windows的注册表: SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
读取注册表循环出list
正则出 “DisplayIcon” 包含“exe” 或 “ico”
key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", 0, _winreg.KEY_ALL_ACCESS)
for i in xrange(0, _winreg.QueryInfoKey(key)[0]-1):
DisplayName = ''
DisplayIcon = ''
try:
key_name_list =_winreg.EnumKey(key, i)
each_key_path = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"+'\\'+key_name_list
each_key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, each_key_path, 0, _winreg.KEY_ALL_ACCESS)
DisplayName, REG_SZ = _winreg.QueryValueEx(each_key, "DisplayName")
DisplayName = DisplayName.encode('utf-8')
try:
DisplayIcon, REG_SZ = _winreg.QueryValueEx(each_key,"DisplayIcon")
DisplayIcon = DisplayIcon.encode('utf-8')
except WindowsError:
pass
#注册表中同时满足DisplayName 和 DisplayIcon
if DisplayName and DisplayIcon:
result = self.orderDict(str(i), DisplayName, DisplayIcon)
except WindowsError:
pass
2.从exe中获取Icon资源
获取到了软件的列表,现在要把列表展示出来,肯定要查看软件的Icon了,所以要从已有的“DisplayIcon” 包含“exe”中读取exe的Icon
通过win32ui,win32gui 来获取exe中的Icon资源
large, small = win32gui.ExtractIconEx(self.numreg[key]['exe'], 0)
self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0]), 2)
def bitmapFromHIcon(self, hIcon):
hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
hbmp = win32ui.CreateBitmap()
hbmp.CreateCompatibleBitmap(hdc, 32, 32)
hdc = hdc.CreateCompatibleDC()
hdc.SelectObject(hbmp)
hdc.DrawIcon((0, 0), hIcon)
hdc.DeleteDC()
return hbmp.GetHandle()
3.QListWidget的Icon模型,与获取item值
在QListWidget 中setViewMode 设置查看的模型中为IconMode ,才可以指定显示的Icon
self.contentsWidget = QtGui.QListWidget()
self.contentsWidget.setViewMode(QtGui.QListView.IconMode)
self.contentsWidget.setIconSize(QtCore.QSize(96, 84)) #Icon 大小
self.contentsWidget.setMovement(QtGui.QListView.Static) #Listview不让列表拖动
self.contentsWidget.setMaximumWidth(800) # 最大宽度
self.contentsWidget.setSpacing(15) # 间距大小
需要获取QListWidget中item。 首先要在定义QlistWidgetItem的时候setData 值
Atem=QtGui.QListWidgetItem(self.contentsWidget)
exeMenu=‘data_string’
Atem.setData(QtCore.Qt.UserRole, exeMenu)
获取:
item = self.contentsWidget.currentItem()
location = item.data(QtCore.Qt.UserRole)
Obj= location.toPyObject()
print(Obj)
4.打开exe文件或目录
打开文件和目录参考: http://www.cnblogs.com/dcb3688/p/4463670.html
if Obj and os.path.exists(Obj): #文件or 目录存在
if os.path.isfile(Obj):
import win32process
try:
win32process.CreateProcess(str(Obj), '',None , None , 0 ,win32process. CREATE_NO_WINDOW , None , None ,win32process.STARTUPINFO())
except Exception, e:
print(e)
else:
os.startfile(str(Obj)) else: # 不存在的目录
QtGui.QMessageBox.warning(self, (u'提示'),(u'无法打开不存在的目录!'),QtGui.QMessageBox.Yes)
完整代码如下:
# -*- coding: UTF8 -*-
from PyQt4 import QtCore, QtGui
import _winreg
import re, sys, os, rcc
import win32ui
import win32gui
reload(sys)
sys.setdefaultencoding("utf-8")
class ListDialog(QtGui.QDialog):
def __init__(self, parent=None):
super(ListDialog, self).__init__(parent) self.contentsWidget = QtGui.QListWidget()
self.contentsWidget.setViewMode(QtGui.QListView.IconMode)
self.contentsWidget.setIconSize(QtCore.QSize(96, 84)) #Icon 大小
self.contentsWidget.setMovement(QtGui.QListView.Static) #Listview不让列表拖动
self.contentsWidget.setMaximumWidth(800) # 最大宽度
self.contentsWidget.setSpacing(15) # 间距大小 winrege= winregeditor()
self.numreg=winrege.getreg()
for key in self.numreg.keys():
Atem=QtGui.QListWidgetItem(self.contentsWidget)
try: # ico 来自exe
large, small = win32gui.ExtractIconEx(self.numreg[key]['exe'], 0)
exeMenu=self.numreg[key]['exe']
win32gui.DestroyIcon(small[0])
self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0]), 2)
except Exception,e: #ico 来自 icon
if self.numreg[key].has_key('icon') and os.path.isfile(self.numreg[key]['icon']): # 判断ico文件是否存在
self.pixmap = QtGui.QPixmap(self.numreg[key]['icon'])
iconMenu = self.numreg[key]['icon']
split = iconMenu.split('\\')
exeMenu ='\\'.join(split[:-1])
else: # 不存在ico文件给定默认图标
self.pixmap = ':default.png'
exeMenu = '' Atem.setIcon(QtGui.QIcon(self.pixmap))
Atem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
Atem.setTextAlignment(QtCore.Qt.AlignHCenter)
Atem.setData(QtCore.Qt.UserRole, exeMenu)
DisplayName=self.numreg[key]['DisplayName'].encode('utf-8')
Atem.setToolTip(u""+DisplayName) # tip 显示
if len(DisplayName)>=6:
DisplayName=DisplayName.decode('utf8')[0:6].encode('utf8')+'…'
Atem.setText(u""+DisplayName) horizontalLayout = QtGui.QHBoxLayout()
horizontalLayout.addWidget(self.contentsWidget)
mainLayout = QtGui.QVBoxLayout()
mainLayout.addLayout(horizontalLayout)
self.setLayout(mainLayout)
self.setWindowTitle(u'Pyqt 显示已安装软件列表')
self.setWindowIcon(QtGui.QIcon(':favicon.ico'))
self.resize(600, 300)
self.contentsWidget.itemDoubleClicked.connect(self.DoubleClicked) #双击事件 # 当窗体大小改变后重新绘制窗体 重新排列Icon效果
def paintEvent(self,event):
mw = self.geometry()
width=mw.width() # 获取窗体宽度
self.contentsWidget.setViewMode(QtGui.QListView.IconMode)
self.contentsWidget.setIconSize(QtCore.QSize(96, 84)) #Icon 大小
self.contentsWidget.setMaximumWidth(width)
self.contentsWidget.setSpacing(12) # 间距大小
# win32 获取exe 资源
def bitmapFromHIcon(self, hIcon):
hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
hbmp = win32ui.CreateBitmap()
hbmp.CreateCompatibleBitmap(hdc, 32, 32)
hdc = hdc.CreateCompatibleDC()
hdc.SelectObject(hbmp)
hdc.DrawIcon((0, 0), hIcon)
hdc.DeleteDC()
return hbmp.GetHandle()
# 双击事件
def DoubleClicked(self):
item = self.contentsWidget.currentItem() # 获取当前item <PyQt4.QtGui.QListWidgetItem object at 0x01775E40>
location = item.data(QtCore.Qt.UserRole) # 获取item里面的data <PyQt4.QtCore.QVariant object at 0x018FD9B0>
Obj= location.toPyObject()
if Obj and os.path.exists(Obj): #文件or 目录存在
if os.path.isfile(Obj):
import win32process
try:
win32process.CreateProcess(str(Obj), '',None , None , 0 ,win32process. CREATE_NO_WINDOW , None , None ,win32process.STARTUPINFO())
except Exception, e:
print(e)
else:
os.startfile(str(Obj)) else: # 不存在的目录
QtGui.QMessageBox.warning(self, (u'提示'),(u'无法打开不存在的目录!'),QtGui.QMessageBox.Yes) # 注册表操作
class winregeditor:
dicList = {} def orderDict(self, numkey, DisplayName, DisplayIcon):
self.dicList[numkey] = {'DisplayName': DisplayName, 'DisplayIcon': DisplayIcon}
exeIcon = re.compile('.*exe')
match = exeIcon.match(DisplayIcon)
if match: #匹配到exe, 可直接打开
self.dicList[numkey]['exe'] = match.group()
else: # 没有exe,Icon可为ico 文件
self.dicList[numkey]['icon'] =DisplayIcon
return self.dicList def getreg(self):
key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", 0, _winreg.KEY_ALL_ACCESS)
for i in xrange(0, _winreg.QueryInfoKey(key)[0]-1):
DisplayName = ''
DisplayIcon = ''
try:
key_name_list =_winreg.EnumKey(key, i)
each_key_path = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"+'\\'+key_name_list
each_key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, each_key_path, 0, _winreg.KEY_ALL_ACCESS)
DisplayName, REG_SZ = _winreg.QueryValueEx(each_key, "DisplayName")
DisplayName = DisplayName.encode('utf-8')
try:
DisplayIcon, REG_SZ = _winreg.QueryValueEx(each_key,"DisplayIcon")
DisplayIcon = DisplayIcon.encode('utf-8')
except WindowsError:
pass
#注册表中同时满足DisplayName 和 DisplayIcon
if DisplayName and DisplayIcon:
result = self.orderDict(str(i), DisplayName, DisplayIcon)
except WindowsError:
pass return result if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
dialog = ListDialog()
dialog.show()
sys.exit(app.exec_())
效果:
控制面板--软件删除:
QlistWidget软件列表效果:
Pyqt 获取windows系统中已安装软件列表的更多相关文章
- 获取Windows系统中的所有可用和在用串口
目的:获取Windows系统中的所有可用和在用串口 方法:注册表查询法 优点:简单.实用.快速.无遗漏,无多余结果. 说明:另外还有8种方法可以枚举串口,但都不如此法. 代码和详细注释如下: //-- ...
- Windows系统中 JDK安装及环境配置
需要安装jdk的第一步就是先去官网下载好JDK,选择需要的版本. Windows系统 1.将下载好的压缩包解压,点击解压得到的jdk执行文件开始安装.在安装过程中会弹出两个安装,一个是jdk,一个是j ...
- 二进制程序分析工具Pin在Windows系统中的安装和使用方法
这篇日志其实很弱智,也是因为换了新电脑,实验环境不全(当然,做这个实验我是在虚拟机里,因为接下来想拿些恶意代码的数据),所以这里记录一下在Windows下怎么安装和使用Pin这个程序分析领域最常用的工 ...
- Windows系统中Xshell与Linux连接时遇到的问题
前提条件:在Windows系统中已经安装了Xshell,并且安装了虚拟机软件和Linux系统 步骤1.在Linux系统中root用户下,使用ifconfig命令查看虚拟系统Linux的IP地址.如图1 ...
- 在Windows系统中安装集成的PHP开发环境
原文:在Windows系统中安装集成的PHP开发环境 刚想学php的,又不会配置复杂php的环境,可以使用集成的,目前网上提供常用的PHP集成环境主要有AppServ.phpStudy.WAMP和XA ...
- python - 在Windows系统中安装Pygame及导入Eclipse
环境:python3.6(只有一个版本)+ windows10(64 bit) + Eclipse+pydev python3.6安装完成后,会自带 easy_install 和 pip3,在Win ...
- linux中安装软件,查看、卸载已安装软件方法
各种主流Linux发行版都采用了某种形式的包管理系统(PMS)来控制软件和库的安装. 软件包存储在服务器上,可以利用本地Linux系统上的PMS工具通过互联网访问.这些服务器称为仓库. 由于Linux ...
- Linux系统上查找已安装软件的路径
在Linux系统上查找已安装软件路径的命令,以查找pcre的安装路径为例: [root@localhost doc]# rpm -ql pcre /lib64/libpcre.so. /lib64/l ...
- windows 如何将安装Anaconda之前已经安装的python版本(中已安装的库)移动到 Anaconda中
题目]如何将安装Anaconda之前已经安装的python版本(中已安装的库)移动到 Anaconda中 一.概述 之前安装tensorflow的安装了anaconda并用它进行安装,anaconda ...
随机推荐
- Hashtable和HashMap的区别举例
我们先看2个类的定义 public class Hashtable extends Dictionary implements Map, Cloneable, java.io.Serializable ...
- CCF 模拟C 找最大矩形+输入输出外挂
http://115.28.138.223:81/view.page?opid=3 统计出连续的最长乘以当前高度,找最大即可 #include<iostream> #include< ...
- Border Tree笔记
最近在学这个东西(当然不是行道树了QAQ..),感觉挺鬼畜的,整个人都不太好了..(特别是鬼畜的sone爷代码与讲稿),感觉他写的并不是普及向算法...?
- 【云计算】docker三剑客如何支持分布式部署?
This blog will explain how to create multi-container application deployed on multiple hosts using Do ...
- Unity Assets目录下的特殊文件夹名称
1.隐藏文件夹以.开头的文件夹会被Unity忽略.在这种文件夹中的资源不会被导入,脚本不会被编译.也不会出现在Project视图中.2.Standard Assets在这个文件夹中的脚本最先被编译.这 ...
- vSphere Client无法连接到服务器 出现未知错误的解决方法
VMware ESXi服务器虚拟机在正常使用过程中,有时候会突然出现远程连接不上的问题,那么这个时候使用vSphere Client连接会出现如下错误: 虽然连接不上,但是可以ping通,所以分析有可 ...
- 9.nodejs权威指南--Socket.IO
1. Socket.IO 1.1 服务器 var http = require('http'); var sio = require('socket.io'); var fs = require('f ...
- MySQL thread pool【转】
本文来自:http://blog.chinaunix.net/uid-26896862-id-3993773.html 刚刚经历了淘宝的双11,真实感受到了紧张的氛围.尽管DB淡定的度过,但是历程中的 ...
- apache的httpd.conf翻译
# This is the main Apache HTTP server configuration file. It contains the 这是Apache HTTP Server的主配置文件 ...
- Java for LeetCode 225 Implement Stack using Queues
Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. po ...