基于pyqt5的系统信息获取软件

基于pyqt5的系统信息获取软件

1,主程序

功能概述:主程序主要控制软件的升级和启动

# -*- coding: utf-8 -*-
import os, sys
import win32api
import win32con 
import time
import json
import threading
import ctypes
import shutil
from subprocess import *
from PyQt5 import QtWidgets  
from PyQt5.QtWidgets import QMessageBox, QDesktopWidget

'''
    思路:下载获取服务器的conf.json文件到temp文件夹
         与本地文件夹下conf.josn文件进行版本号比较
         若版本号大于本地版本号,则下载exe文件到temp
         文件夹,进行更新若匹配,则不进行操作
'''

class MyWindow(QtWidgets.QWidget):   
    #构造函数
    def __init__(self):
        super(MyWindow,self).__init__()
        self.autoStartUp()
        #启动线程下载配置文件,查询是否有新版本
        #t1 = threading.Thread(target=self.download('url1'))
        #t1.start()    
        while not(self.isUpdate()):
            print('查询是否有更新')
            time.sleep(10)
        print('软件有更新!')
        #t2 = threading.Thread(target=self.download('url2'))
        #t2.start()  
        while True:
            if os.path.exists('./temp/BSSmain.exe'):
                print('软件已下载完成,正在安装更新!')
                self.update()
                break   #跳出while循环!
            print('等待软件下载完成!')
            time.sleep(3)
        sys.exit(0)

    #设置窗口中心显示       
    def windowCenter(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
    #自启动函数       
    def autoStartUp(self):
        (path, name) = os.path.split(sys.argv[0])
        path1 = path + '\\bin\\BSSmain.exe'
        print(path1)
        path2 = path + '\\BSS.exe'
        #time.sleep(1)
        if os.path.exists(path1):
            Popen(path1, creationflags=CREATE_NEW_CONSOLE)
        if os.path.exists(path2):
            runpath = "Software\\Microsoft\\Windows\\CurrentVersion\\Run"  
            hKey = win32api.RegOpenKeyEx(win32con.HKEY_CURRENT_USER, runpath, 0, win32con.KEY_SET_VALUE)  
            #(filepath, filename) = os.path.split(path2)  
            win32api.RegSetValueEx(hKey, "BSS", 0, win32con.REG_SZ, path2)
            win32api.RegCloseKey(hKey)            
    #下载函数
    def download(self, url):
        (path, name) = os.path.split(sys.argv[0])
        #url = 'http://pic.58pic.com/58pic/15/64/95/00v58PICESr_1024.jpg'  
        #local是指定的文件存储的目录  
        local = path + '\\temp'  
        path = local + url.split('/')[-1]
        print(path)  
        try:  
            if not os.path.exists(local):  
                os.mkdir(local)  
            if not os.path.exists(path):  
                r = requests.get(url)  
                with open(path,'wb') as f:  
                    f.write(r.content)  
                    f.close()  
                    print('软件包下载完成')
                    return 1
            else:  
                print('文件已存在')  
                return 1
        except:  
           print('爬取失败')
           return 0
    #判断是否升级函数
    def isUpdate(self):
        (path, name) = os.path.split(sys.argv[0])
        path3 = path + '\\conf.json'
        path5 = path + '\\temp\\conf.json'
        if os.path.exists(path5):   
            fileNew = open(path5, encoding='utf-8')
        else:
            return 0
        if os.path.exists(path3):
            fileOld = open(path3, encoding='utf-8')
        else:
            return 0
        new = json.load(fileNew)
        old = json.load(fileOld)
        verN = new['version']
        verO = old['version']
        fileNew.close()
        fileOld.close()
        if verN > verO: #若版本号不同,则更新 
            return 1
        else:
            return 0
    #软件更新函数              
    def update(self):
        (path, name) = os.path.split(sys.argv[0])
        path1 = path + '\\bin\\BSSmain.exe'
        path3 = path + '\\conf.json'
        path4 = path + '\\temp\\BSSmain.exe'
        path5 = path + '\\temp\\conf.json'
        self.windowCenter()
        reply = QMessageBox.information(self, '信息',  
                                        '检测到BSS新版本,立即更新!',  
                                        QMessageBox.Yes)       
        if reply == QMessageBox.Yes:
            Popen('taskkill /IM BSSmain.exe /F',creationflags=CREATE_NEW_CONSOLE)#直接关闭主进程 
            time.sleep(5)          
            #cmd1 = 'replace /r' + ' ' + path4 + ' ' + path
            if os.path.exists(path4):
                os.remove(path1)
                shutil.move(path4, path)

            #cmd2 = 'replace /r' + ' ' + path5 + ' ' + path 
            if os.path.exists(path5):
                os.remove(path3)
                shutil.move(path5, path)
                #Popen(cmd2)
                #os.remove(path5)
            reply = QMessageBox.information(self,'信息', 
                                    '软件已更新完毕!',
                                    QMessageBox.Yes)
            if reply == QMessageBox.Yes:
                #重新启动exe文件
                if os.path.exists(path1):
                    Popen(path1, creationflags=CREATE_NEW_CONSOLE)
        else:
            pass

if __name__=="__main__":    
    app=QtWidgets.QApplication(sys.argv)    
    myshow=MyWindow()
    sys.exit(app.exec_())    

2,获取本地信息程序

功能概述:获取电脑的硬件信息以及动态信息

# -*- coding: utf-8 -*-
import sys, os, re, wmi, time
import platform, winreg, psutil
import ctypes, json, subprocess
import win32event, win32con
import win32api, pywintypes
from PyQt5.QtWidgets import *
from PyQt5.QtCore    import *
from PyQt5.QtGui     import *

class TrayIcon(QSystemTrayIcon):
    def __init__(self, parent=None):
        super(TrayIcon, self).__init__(parent)
        self.showMenu()
        self.other()

    def showMenu(self):
        "设计托盘的菜单"
        self.menu = QMenu()
        self.quitAction = QAction("退出", self, triggered=self.quit)
        self.menu.addAction(self.quitAction)
        self.setContextMenu(self.menu)

    def other(self):
        self.activated.connect(self.iconClied)
        #把鼠标点击图标的信号和槽连接
        (path, name) = os.path.split(sys.argv[0])
        print(path)
        self.setIcon(QIcon(path + "\\icon\\icon.png"))
        #self.setIcon(QIcon('./icon/icon.png'))
        self.icon = self.MessageIcon()
        #设置图标       
    def iconClied(self, reason):
        "鼠标点击icon传递的信号会带有一个整形的值,1是表示单击右键,2是双击,3是单击左键,4是用鼠标中键点击"
        if reason == 2 or reason == 3:
            pw = self.parent()
            if pw.isVisible():
                pw.hide()
            else:
                pw.show()

    def quit(self):
        self.setVisible(False)
        self.parent().close()
        qApp.quit()
        sys.exit()

class MyThread(QThread):  
    trigger = pyqtSignal()  
    sec = 300
    def __init__(self, parent=None):  
        super().__init__(parent)

    def run(self):
        while True:
            self.trigger.emit()         #循环完毕后发出信号
            time.sleep(self.sec)

class BSS(QMainWindow):
    def __init__(self):
        super(BSS,self).__init__()
        self.initUI()   

    def initUI(self):
        (path, name) = os.path.split(sys.argv[0])    
        self.sysPlatform()
        self.login()

        self.thread = MyThread()
        self.thread.trigger.connect(self.autoPost) # 线程发过来的信号挂接到槽:autoPost
        self.thread.start()  

        exitAction = QAction(QIcon(path + '\\icon\\exitIcon.png'), 'Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit')
        exitAction.triggered.connect(self.close)

        sysInfo = QAction(QIcon(path + '\\icon\\infoIcon.png'), 'Sys Info', self)
        sysInfo.setShortcut('Ctrl+W')
        sysInfo.setStatusTip('Sys Info')
        sysInfo.triggered.connect(self.sysPlatform)

        softList = QAction(QIcon(path + '\\icon\\softIcon.png'), 'Soft List', self)
        softList.setShortcut('Ctrl+A')
        softList.setStatusTip('Soft List')
        softList.triggered.connect(self.softwareList)

        procList = QAction(QIcon(path + '\\icon\\procIcon.png'), 'Proc list', self)
        procList.setShortcut('Ctrl+S')
        procList.setStatusTip('Proc List')
        procList.triggered.connect(self.processList)

        self.statusBar()

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(exitAction)

        toolbar = self.addToolBar('Sys Info')
        toolbar.addAction(sysInfo)

        toolbar = self.addToolBar('Soft List')
        toolbar.addAction(softList)

        toolbar = self.addToolBar('Proc List')
        toolbar.addAction(procList)

        toolbar = self.addToolBar('Exit')
        toolbar.addAction(exitAction)

        self.setGeometry(300, 300, 700, 450)
        self.windowCenter()
        self.setWindowTitle('系统基本信息')   
        self.tray_icon = TrayIcon(self)
        self.tray_icon.show()

    #重写退出程序,改成只是隐藏界面
    def closeEvent(self, event):
        self.hide()
        event.ignore()

    def buttom(self):
        # 修改
        widget=QWidget()
        updateBtn = QPushButton('确定')
        updateBtn.setStyleSheet("QPushButton{background-color:black; color:white; border-radius:10px; border:2px groove gray; border-style:outset;}"
                                "QPushButton:hover{background-color:white; color:black;}"
                                "QPushButton:pressed{background-color:rgb(85, 170, 255);border-style: inset;}"
                                );

        updateBtn.clicked.connect(lambda:self.post())
        hLayout = QHBoxLayout()
        hLayout.addWidget(updateBtn)
        hLayout.setContentsMargins(5,2,5,2)
        widget.setLayout(hLayout)
        return widget

    def login(self): 
        #self.sysPlatform()
        dock=QDockWidget(self.tr("人员登记"),self)  
        dock.setFixedSize(150, 450)
        dock.setFeatures(QDockWidget.DockWidgetMovable)  
        dock.setAllowedAreas(Qt.LeftDockWidgetArea|Qt.RightDockWidgetArea)  

        verticalHeader = ["姓名", "电话", "部门", '定时', '上传']
        self.table = QTableWidget()
        #self.setCentralWidget(self.table)#注意这个功能很重要,添加各种东西到界面上的接口
        self.table.setColumnCount(1)
        self.table.setRowCount(5)
        self.table.setVerticalHeaderLabels(verticalHeader)
        self.table.setEditTriggers(QTableWidget.DoubleClicked)
        self.table.setSelectionBehavior(QTableWidget.SelectRows)
        self.table.setSelectionMode(QTableWidget.SingleSelection)
        self.table.horizontalHeader().setVisible(False)
        for index in range(self.table.rowCount()):
            headItem = self.table.verticalHeaderItem(index)
        self.table.setColumnWidth(0,100)
        self.name = QTableWidgetItem("")
        self.table.setItem(0,0, self.name)
        self.phone = QTableWidgetItem("")
        self.table.setItem(0,1, self.phone)
        genderComb1 = QComboBox()
        self.depat = genderComb1
        genderComb1.addItem(r"系统集成部")
        genderComb1.addItem(r"电信软件部")
        genderComb1.setCurrentIndex(0)
        self.table.setCellWidget(2,0,genderComb1)
        genderComb2 = QComboBox()
        self.timing = genderComb2
        genderComb2.addItem("5min")
        genderComb2.addItem("10min")
        genderComb2.addItem("15min")
        genderComb2.setCurrentIndex(0)
        self.table.setCellWidget(3,0,genderComb2)
        self.table.setCellWidget(4,0,self.buttom())      
        #停靠窗口
        dock.setWidget(self.table)  
        self.addDockWidget(Qt.RightDockWidgetArea,dock) 

    def windowCenter(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())


    def post(self):
        #获取文本框内容
        (path, name) = os.path.split(sys.argv[0])
        name = self.name.text()  
        self.postData['name'] = str(name)
        phone = self.phone.text()
        self.postData['phone'] = str(phone)
        depat = self.depat.currentText()
        self.postData['depat'] = depat
        print(self.postData)
        postJsonData = json.dumps(self.postData, ensure_ascii=False)
        f = open(path + '\\upload\\info.json', 'w')
        print(postJsonData)
        f.write(postJsonData)
        f.close()

        timing = self.timing.currentText()       
        #定时上传数据
        self.thread.terminate()
        if timing == '5min':
            self.thread = MyThread() # 创建一个线程 
        elif timing == '10min':
            self.thread = MyThread()
            self.thread.sec = 600
        else:
            self.thread = MyThread()
            self.thread.sec = 900
        self.thread.trigger.connect(self.autoPost) # 线程发过来的信号挂接到槽:autoPost
        self.thread.start()

        #手动上传系统信息及个人信息
        print('上传成功!')

    def sysPlatform(self):
        self.textE1 = QTextEdit()
        self.textE1.setFontPointSize(16)
        self.textE1.setFontWeight(75)
        self.textE1.setText('系统硬件配置参数')
        self.setCentralWidget(self.textE1)
        self.textE1.setFontWeight(50)
        self.textE1.setFontPointSize(11)
        self.postData = {}
        key = ['操作系统', '操作系统的位数', 'cpu型号', '网卡', 'IP地址', 'mac地址', '硬盘', '键盘', '主板', '声卡', '显示器', '显卡']
        val = []
        #操作系统
        pf = platform.platform()        
        #cpu型号
        w = wmi.WMI()
        cpu = w.Win32_Processor()[0]
        #硬盘
        dd = w.Win32_DiskDrive()[0]
        #键盘
        kb = w.Win32_Keyboard()[0]
        #主板
        bb = w.Win32_BaseBoard()[0]
        #声卡
        sd = w.Win32_SoundDevice()[0]
        #显示器
        dm = w.Win32_DesktopMonitor()[0]
        #显卡
        dp = w.Win32_DisplayConfiguration()[0]       
        #网卡
        nw = w.Win32_NetworkAdapter()[0]
        #网卡ip和mac地址
        adr = []  
        nd = psutil.net_if_addrs()  
        for k, v in nd.items():
            for item in v:  
                if item[0] == 2 and not item[1]=='127.0.0.1':  
                    adr.append((k, item[1]))#ip地址
                if '-' in item[1] and len(item[1])==17: 
                    adr.append((k, item[1]))#mac地址
        val.append(pf)
        self.postData['os'] = pf
        val.append(str(cpu.AddressWidth) + 'bit')
        self.postData['osAddressWidth'] = cpu.AddressWidth
        val.append(cpu.Name)
        self.postData['cpu'] = cpu.Name
        val.append(nw.Name)
        self.postData['netWorkCard'] = nw.Name
        val.append(adr[1][1])
        self.postData['ip'] = adr[1][1]
        val.append(adr[0][1])
        self.postData['mac'] = adr[0][1]
        val.append(dd.Caption)
        self.postData['diskDrive'] = dd.Caption
        val.append(kb.Caption)
        self.postData['keyBoard'] = kb.Caption
        val.append(bb.Product)
        self.postData['baseBoard'] = bb.Product
        val.append(sd.Name)
        self.postData['soundDevice'] = sd.Name
        val.append(dm.Name)
        self.postData['monitor'] = dm.Name
        val.append(dp.Caption)    
        self.postData['graphicsCard'] = dp.Caption     

        for i, j in zip(key, val):
            item = i + ' = ' + j
            self.textE1.append(item)

        self.textE1.setFontPointSize(16)
        self.textE1.setFontWeight(75)
        self.textE1.append('系统动态信息')
        self.textE1.setFontWeight(50)
        self.textE1.setFontPointSize(11)
        #cpu运行情况
        cpu = psutil.cpu_times_percent(interval=1.00)        
        item = 'cpu占用情况 : ' + '用户 : ' + str(cpu.user) + '%' + '  系统 : ' + str(cpu.system) + '%' + '  空闲 : ' + str(cpu.idle) + '%'
        self.textE1.append(item)
        self.autoPostData = {}
        data = {'user':cpu.user, 'system':cpu.system, 'idle':cpu.idle, 'interrupt':cpu.interrupt, 'dpc':cpu.dpc}
        self.autoPostData['cpuUsePercentage'] = data     
        self.postData['cpuUsePercentage'] = data
        #运行内存大小
        men = psutil.virtual_memory()
        item = '内存大小 : ' + str(round(men.total/1024/1024/1024)) + 'g' + '  已占用 : ' + str(round(men.used/1024/1024/1024, 2)) + 'g' + '  占用率 : ' + str(round(men.percent, 1))+'%'
        self.textE1.append(item)
        self.autoPostData['memoryUsePercentage'] = round(men.percent, 1)
        self.postData['memoryUsePercentage'] = round(men.percent, 1)
        #各分区
        dev = []
        total = []
        free = []
        used = []
        per = []
        p = psutil.disk_partitions()
        j = 0
        for i in p:
            if (str(p[j].fstype) != ''):
                dev.append(str(p[j].device))
                #print(psutil.disk_usage(str(p[j].device)))  #获取各个分区的状态
                total.append(str(round(psutil.disk_usage(str(p[j].device)).total/1024/1024/1024)) + 'g')
                free.append(str(round(psutil.disk_usage(str(p[j].device)).free/1024/1024/1024)) + 'g')
                used.append(str(round(psutil.disk_usage(str(p[j].device)).used/1024/1024/1024)) + 'g')
                per.append(str(round(psutil.disk_usage(str(p[j].device)).percent, 1)) + '%')
                item = '盘符 : ' + dev[j] + '  总共 : ' + total[j] + '  剩余 : ' +free[j] + '  已使用 : ' + used[j] + '  使用率 : ' + per[j]
                self.textE1.append(item)                
                j += 1
        diskIoCounters = psutil.disk_io_counters()
        item = '硬盘读取情况 : ' + str(diskIoCounters)
        self.textE1.append(item)
        self.textE1.setReadOnly(True)
        data = {'read_count':diskIoCounters.read_count, 'write_count':diskIoCounters.write_count, 'read_bytes':diskIoCounters.read_bytes, \
                'write_bytes':diskIoCounters.write_bytes, 'read_time':diskIoCounters.read_time, 'write_time':diskIoCounters.write_time}
        self.autoPostData['diskIoCounters'] = data
        self.postData['diskIoCounters'] = data

    def softwareList(self):
        data = []
        self.textE2 = QTextEdit()
        self.textE2.setFontPointSize(16)
        self.textE2.setFontWeight(75)
        self.textE2.setText('系统安装软件列表')
        self.setCentralWidget(self.textE2)
        self.textE2.setFontWeight(50)
        self.textE2.setFontPointSize(11)
        sub_key=[r'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall', r'SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall']
        for k in sub_key:
            try:
                key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, k, 1, winreg.KEY_READ)
                i = winreg.QueryInfoKey(key)[0]-1
                #print('i = ', i)
                for j in range(0,i):
                    #print('j = ', j)
                    subkey_name = winreg.EnumKey(key, j)
                    #print(subkey_name)
                    subkey = winreg.OpenKey(key, subkey_name)
                    #print(subkey)
                    try:
                        #m = winreg.QueryInfoKey(subkey)[1]
                        #for n in range(0, m):
                        #    temp = winreg.EnumValue(subkey, n)
                        #    self.textE2.append(str(temp))
                        #    data.append(temp)

                        displayname,d = winreg.QueryValueEx(subkey, u'DisplayName')
                        self.textE2.append('DisplayName = ' + displayname)

                        #displayVersion,d = winreg.QueryValueEx(subkey, u'DisplayVersion')
                        #self.textE2.append('DisplayVersion = ' + displayVersion)
                        #
                        #Publisher,d = winreg.QueryValueEx(subkey, u'Publisher')
                        #self.textE2.append('Publisher = ' + Publisher)
                        #
                        #InstallLocation,d = winreg.QueryValueEx(subkey, u'InstallLocation')
                        #self.textE2.append('InstallLocation = ' + InstallLocation)
                        #
                        #UninstallString,d = winreg.QueryValueEx(subkey, u'UninstallString')
                        #self.textE2.append('UninstallString = ' + UninstallString)

                    except Exception:
                        pass
                    #self.textE2.append('')
                    winreg.CloseKey(subkey)
            except WindowsError:
                pass
            finally:
                self.textE2.append('----------------------------------------')
                self.textE2.append('----------------------------------------')
            self.textE2.setReadOnly(True)

    def processList(self):
        p = []
        self.textE3 = QTextEdit()
        self.textE3.setFontPointSize(16)
        self.textE3.setFontWeight(75)
        self.textE3.setText('系统正在运行的程序')
        self.setCentralWidget(self.textE3)
        self.textE3.setFontWeight(50)
        self.textE3.setFontPointSize(11)  
        for proc in psutil.process_iter():
            try:
                pinfo = proc.as_dict(attrs=['name', 'pid'])
                p.append(pinfo)
            except psutil.NoSuchProcess:
                pass
            else:
                self.textE3.append(str(pinfo))      
        self.textE3.setReadOnly(True)

    def autoPost(self):
        (path, name) = os.path.split(sys.argv[0])
        p = []
        for proc in psutil.process_iter():
            try:
                pinfo = proc.as_dict(attrs=['name', 'pid'])
                p.append(pinfo)
            except psutil.NoSuchProcess:
                pass
        self.autoPostData['process'] = p
        postJsonData = json.dumps(self.autoPostData, ensure_ascii=False)
        f = open(path + '\\upload\\sysDynaInfo.json', 'w')
        f.write(postJsonData)
        f.close()

if __name__ == '__main__':   
    ERROR_ALREADY_EXISTS = 183 
    sz_mutex = "BSS_mutex" 
    hmutex = win32event.CreateMutex(None, pywintypes.FALSE,sz_mutex) 
    if (win32api.GetLastError() == ERROR_ALREADY_EXISTS): 
        sys.exit(0)
    else:
        time.sleep(0.5)
    app = QApplication(sys.argv)
    ex = BSS()
    sys.exit(app.exec_()) 
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值