Я пытаюсь реализовать кнопку «самообновления» в приложении PyQt5.Я создаю исполняемый файл с pyinstaller SelfUpdate.py --onefile
.Если у меня будет новая скомпилированная версия моего приложения, я помещу ее в каталог загрузки в сети.Программа запускается разными пользователями на их ПК, и если кто-то нажимает кнопку обновления, его / ее приложение должно быть заменено новым.Я работаю над Win7 / 64, Python 3.6.3.
Я еще не нашел код Python для этого, но здесь Я нашел описание, которое я адаптировал:
- скопировать новый .exe из каталога обновлений в локальный .ex_
- удалить старый .bak, если он существует
- переименовать запущенную программу .exe в .bak
- переименоватьновая программа .ex_ в .exe
- запустить обновленную программу .exe как самостоятельный процесс
- выйти из запущенной в данный момент устаревшей программы
Мой минимальный пример кода следующий.В конце концов, другие файлы и каталоги также должны быть заменены.Кажется, он работает и в основном делает то, что я хочу, однако я хотел бы знать: это путь или есть, возможно, более простые / умные / лучшие способы достижения такой кнопки самообновления?
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_())