Pyqt 獲取windows系統中已安裝軟件列表


開始之前的基礎知識

 1. 獲取軟件列表

在Python的標准庫中,_winreg可以操作Windows的注冊表。
獲取已經安裝的軟件列表一般是讀去windows的注冊表: SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
讀取注冊表循環出list
正則出 “DisplayIcon” 包含“exe” 或 “ico”

 1         key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", 0, _winreg.KEY_ALL_ACCESS)
 2         for i in xrange(0, _winreg.QueryInfoKey(key)[0]-1):
 3             DisplayName = ''
 4             DisplayIcon = ''
 5             try:
 6                  key_name_list =_winreg.EnumKey(key, i)
 7                  each_key_path = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"+'\\'+key_name_list
 8                  each_key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, each_key_path, 0, _winreg.KEY_ALL_ACCESS)
 9                  DisplayName, REG_SZ = _winreg.QueryValueEx(each_key, "DisplayName")
10                  DisplayName = DisplayName.encode('utf-8')
11                  try:
12                      DisplayIcon, REG_SZ = _winreg.QueryValueEx(each_key,"DisplayIcon")
13                      DisplayIcon = DisplayIcon.encode('utf-8')
14                  except WindowsError:
15                      pass
16                  #注冊表中同時滿足DisplayName 和 DisplayIcon
17                  if DisplayName and DisplayIcon:
18                      result = self.orderDict(str(i), DisplayName, DisplayIcon)
19             except WindowsError:
20                 pass

2.從exe中獲取Icon資源

獲取到了軟件的列表,現在要把列表展示出來,肯定要查看軟件的Icon了,所以要從已有的“DisplayIcon” 包含“exe”中讀取exe的Icon
通過win32ui,win32gui 來獲取exe中的Icon資源

 1 large, small = win32gui.ExtractIconEx(self.numreg[key]['exe'], 0)
 2 self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0]), 2)
 3 def bitmapFromHIcon(self, hIcon):
 4         hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
 5         hbmp = win32ui.CreateBitmap()
 6         hbmp.CreateCompatibleBitmap(hdc, 32, 32)
 7         hdc = hdc.CreateCompatibleDC()
 8         hdc.SelectObject(hbmp)
 9         hdc.DrawIcon((0, 0), hIcon)
10         hdc.DeleteDC()
11         return hbmp.GetHandle()

3.QListWidget的Icon模型,與獲取item值

在QListWidget 中setViewMode 設置查看的模型中為IconMode  ,才可以指定顯示的Icon

1         self.contentsWidget = QtGui.QListWidget()
2         self.contentsWidget.setViewMode(QtGui.QListView.IconMode)
3         self.contentsWidget.setIconSize(QtCore.QSize(96, 84))  #Icon 大小
4         self.contentsWidget.setMovement(QtGui.QListView.Static)  #Listview不讓列表拖動
5         self.contentsWidget.setMaximumWidth(800)  # 最大寬度
6         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)

 

完整代碼如下:

  1 # -*- coding: UTF8 -*-
  2 from PyQt4 import QtCore, QtGui
  3 import _winreg
  4 import re, sys, os, rcc
  5 import win32ui
  6 import win32gui
  7 reload(sys)
  8 sys.setdefaultencoding("utf-8")
  9 class ListDialog(QtGui.QDialog):
 10     def __init__(self, parent=None):
 11         super(ListDialog, self).__init__(parent)
 12 
 13         self.contentsWidget = QtGui.QListWidget()
 14         self.contentsWidget.setViewMode(QtGui.QListView.IconMode)
 15         self.contentsWidget.setIconSize(QtCore.QSize(96, 84))  #Icon 大小
 16         self.contentsWidget.setMovement(QtGui.QListView.Static)  #Listview不讓列表拖動
 17         self.contentsWidget.setMaximumWidth(800)  # 最大寬度
 18         self.contentsWidget.setSpacing(15)  # 間距大小
 19 
 20         winrege= winregeditor()
 21         self.numreg=winrege.getreg()
 22         for key in self.numreg.keys():
 23             Atem=QtGui.QListWidgetItem(self.contentsWidget)
 24             try:  # ico 來自exe
 25                 large, small = win32gui.ExtractIconEx(self.numreg[key]['exe'], 0)
 26                 exeMenu=self.numreg[key]['exe']
 27                 win32gui.DestroyIcon(small[0])
 28                 self.pixmap = QtGui.QPixmap.fromWinHBITMAP(self.bitmapFromHIcon(large[0]), 2)
 29             except Exception,e:  #ico 來自 icon
 30                 if self.numreg[key].has_key('icon') and os.path.isfile(self.numreg[key]['icon']):  # 判斷ico文件是否存在
 31                     self.pixmap = QtGui.QPixmap(self.numreg[key]['icon'])
 32                     iconMenu = self.numreg[key]['icon']
 33                     split = iconMenu.split('\\')
 34                     exeMenu ='\\'.join(split[:-1])
 35                 else:  # 不存在ico文件給定默認圖標
 36                     self.pixmap = ':default.png'
 37                     exeMenu = ''
 38 
 39             Atem.setIcon(QtGui.QIcon(self.pixmap))
 40             Atem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
 41             Atem.setTextAlignment(QtCore.Qt.AlignHCenter)
 42             Atem.setData(QtCore.Qt.UserRole, exeMenu)
 43             DisplayName=self.numreg[key]['DisplayName'].encode('utf-8')
 44             Atem.setToolTip(u""+DisplayName)  # tip 顯示
 45             if len(DisplayName)>=6:
 46                 DisplayName=DisplayName.decode('utf8')[0:6].encode('utf8')+''
 47             Atem.setText(u""+DisplayName)
 48             
 49             
 50         horizontalLayout = QtGui.QHBoxLayout()
 51         horizontalLayout.addWidget(self.contentsWidget)
 52         mainLayout = QtGui.QVBoxLayout()
 53         mainLayout.addLayout(horizontalLayout)
 54         self.setLayout(mainLayout)
 55         self.setWindowTitle(u'Pyqt 顯示已安裝軟件列表')
 56         self.setWindowIcon(QtGui.QIcon(':favicon.ico'))
 57         self.resize(600, 300)
 58         self.contentsWidget.itemDoubleClicked.connect(self.DoubleClicked)  #雙擊事件
 59         
 60         
 61     # 當窗體大小改變后重新繪制窗體   重新排列Icon效果
 62     def paintEvent(self,event):
 63         mw = self.geometry()
 64         width=mw.width()  # 獲取窗體寬度
 65         self.contentsWidget.setViewMode(QtGui.QListView.IconMode)
 66         self.contentsWidget.setIconSize(QtCore.QSize(96, 84))  #Icon 大小
 67         self.contentsWidget.setMaximumWidth(width)
 68         self.contentsWidget.setSpacing(12)  # 間距大小
 69     # win32 獲取exe 資源
 70     def bitmapFromHIcon(self, hIcon):
 71         hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
 72         hbmp = win32ui.CreateBitmap()
 73         hbmp.CreateCompatibleBitmap(hdc, 32, 32)
 74         hdc = hdc.CreateCompatibleDC()
 75         hdc.SelectObject(hbmp)
 76         hdc.DrawIcon((0, 0), hIcon)
 77         hdc.DeleteDC()
 78         return hbmp.GetHandle()
 79     # 雙擊事件
 80     def DoubleClicked(self):
 81         item = self.contentsWidget.currentItem()   # 獲取當前item   <PyQt4.QtGui.QListWidgetItem object at 0x01775E40>
 82         location = item.data(QtCore.Qt.UserRole)    # 獲取item里面的data  <PyQt4.QtCore.QVariant object at 0x018FD9B0>
 83         Obj= location.toPyObject()
 84         if Obj and os.path.exists(Obj):  #文件or 目錄存在
 85             if os.path.isfile(Obj):
 86                 import win32process
 87                 try:
 88                     win32process.CreateProcess(str(Obj), '',None , None , 0 ,win32process. CREATE_NO_WINDOW , None , None ,win32process.STARTUPINFO())
 89                 except Exception, e:
 90                     print(e)
 91             else:
 92                 os.startfile(str(Obj))
 93 
 94         else:  # 不存在的目錄
 95             QtGui.QMessageBox.warning(self, (u'提示'),(u'無法打開不存在的目錄!'),QtGui.QMessageBox.Yes)
 96 
 97         
 98         
 99         
100 # 注冊表操作
101 class winregeditor:
102     dicList = {}
103 
104     def orderDict(self, numkey, DisplayName, DisplayIcon):
105         self.dicList[numkey] = {'DisplayName': DisplayName, 'DisplayIcon': DisplayIcon}
106         exeIcon = re.compile('.*exe')
107         match = exeIcon.match(DisplayIcon)
108         if match: #匹配到exe, 可直接打開
109             self.dicList[numkey]['exe'] = match.group()
110         else:  # 沒有exe,Icon可為ico 文件
111             self.dicList[numkey]['icon'] =DisplayIcon
112         return self.dicList
113 
114 
115     def getreg(self):
116         key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", 0, _winreg.KEY_ALL_ACCESS)
117         for i in xrange(0, _winreg.QueryInfoKey(key)[0]-1):
118             DisplayName = ''
119             DisplayIcon = ''
120             try:
121                  key_name_list =_winreg.EnumKey(key, i)
122                  each_key_path = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"+'\\'+key_name_list
123                  each_key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, each_key_path, 0, _winreg.KEY_ALL_ACCESS)
124                  DisplayName, REG_SZ = _winreg.QueryValueEx(each_key, "DisplayName")
125                  DisplayName = DisplayName.encode('utf-8')
126                  try:
127                      DisplayIcon, REG_SZ = _winreg.QueryValueEx(each_key,"DisplayIcon")
128                      DisplayIcon = DisplayIcon.encode('utf-8')
129                  except WindowsError:
130                      pass
131                  #注冊表中同時滿足DisplayName 和 DisplayIcon
132                  if DisplayName and DisplayIcon:
133                      result = self.orderDict(str(i), DisplayName, DisplayIcon)
134             except WindowsError:
135                 pass
136 
137         return result
138 
139 
140 
141          
142 if __name__ == '__main__':
143     app = QtGui.QApplication(sys.argv)
144     dialog = ListDialog()
145     dialog.show()
146     sys.exit(app.exec_())

效果:

控制面板--軟件刪除:

QlistWidget軟件列表效果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM