PyQt:如何实现一个自我更新的可执行文件?

时间:2019-03-21 21:43:10

标签: python python-3.x pyqt pyinstaller self-updating

我正在尝试在PyQt5应用程序中实现“自我更新”按钮。我用pyinstaller SelfUpdate.py --onefile创建了一个可执行文件。如果我的应用程序有新的编译版本,则将其放置在网络上的下载目录中。该程序由不同的用户在其PC上运行,如果有人按下了更新按钮,则应将其应用程序替换为新的应用程序。我正在使用Win7 / 64,Python 3.6.3。

我还没有找到用于此目的的Python代码,但是here我找到了一个适应我的描述:

  1. 将新.exe从更新目录复制到本地.ex _
  2. 删除旧的.bak(如果存在)
  3. 将运行程序.exe重命名为.bak
  4. 将新程序.ex_重命名为.exe
  5. 作为独立进程启动更新的程序.exe
  6. 退出当前正在运行的过期程序

我的最小示例代码如下。最后,其他文件和目录也需要替换。它似乎可以运行,并且基本上可以执行我想要的操作,但是,我想知道:这是要走的路还是实现这种自我更新按钮的更简单/更智能/更好的方法?

import sys,shutil,os,time
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox 
import subprocess
from datetime import datetime

class MyWindow(QWidget):
    def __init__(self):
        super(MyWindow,self).__init__()
        self.setWindowTitle('Self updating pogram')
        self.setGeometry(100,100,200,100)
        self.pb_update = QPushButton('Check for updates',self)
        self.pb_update.move(50,20)
        self.pb_update.clicked.connect(self.pb_update_clicked)

    def pb_update_clicked(self):
        dir_download = r'C:\User\Code\NewestVersion'
        fname = "SelfUpdate.exe"
        ffname_update = os.path.join(dir_download,fname)
        time_update = os.path.getmtime(ffname_update)
        time_current = os.path.getmtime(fname)
        print(ffname_update, "\n", datetime.fromtimestamp(time_update).isoformat())
        print(fname, "\n", datetime.fromtimestamp(time_current).isoformat())
        if (time_update > time_current):
            title = "Check for updates"
            message = "Do you want to update?"
            response = QMessageBox.question(self, title, message, QMessageBox.Yes | QMessageBox.No)
            if response == QMessageBox.Yes:
                print("File will be updated. Please wait...")
                shutil.copy2(ffname_update,fname[:-4]+'.ex_') # copy new file to .ex_
                if os.path.isfile(fname[:-4]+'.bak'):
                    os.remove(fname[:-4]+'.bak')              # remove previous .bak
                os.rename(fname,fname[:-4]+'.bak')            # rename running programm to .bak
                os.rename(fname[:-4]+'.ex_',fname)            # rename new program .ex_ to .exe
                subprocess.Popen([fname],close_fds=True)      # start updated program as independent process
                sys.exit()                                    # exit old program
        else:
            print("No update available.")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyle("plastique")
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())

0 个答案:

没有答案