最近我一直在为我的github程序开发自动更新功能。
我想要的效果是,运行以下函数后,如果有更新的版本,则在启动下载的新安装程序之前,必须完全关闭当前程序。
安装程序必须静默启动,并正常安装新程序。
以前发现只要杀掉python程序,无论用什么方法启动安装程序,installer.exe总是一起关闭。
但是后来我发现,当我用pyinstaller打包程序并运行打包的.exe文件时,这个问题就会消失,但由于以下问题仍然不完美:
问题是,只要原程序结束就会弹出cmd控制台
相关代码如下:
def update_checker(ask_update=False):
has_newer = is_mf_need_update()
if has_newer and tkinter.messagebox.askyesno(
title='...', message='need update?'):
root.withdraw()
tkinter.messagebox.showinfo(
title='...', message='update_downloading')
new_exe_name = has_new_installer_downloaded() # returns the name of the newly downloaded installer.exe
if not new_exe_name:
tkinter.messagebox.showerror(
title='...', message='update_download_failed')
return # Do not exit
# Problem's here
os.system(f'"{os.path.join(DOWNLOAD_TEMP_PATH, new_exe_name)}"')
exit_program() # destroy the tkinter root, and so on
elif not has_newer and ask_update: # Proactively update
tkinter.messagebox.showinfo(
title='...', message='update_no_newer')
我知道有一个解决方案,例如启动另一个程序来启动安装程序,但这样的程序会占用更多空间,更重要的是,安装后之前运行的整个程序将被完全重写。所以我认为这是行不通的。
我尝试了“start \B [installer_route]”命令,但这不起作用,也许这是另一种方式?
ps:如果上一个程序不退出,cmd窗口就不会出现,但我必须杀死上一个程序
有什么好的解决方案吗?我的意思是,只要让 cmd 窗口消失,现在就完美了
from subprocess import Popen, CREATE_NO_WINDOW, DETACHED_PROCESS, CREATE_NEW_PROCESS_GROUP
'''
Replace
os.system(f'"{os.path.join(DOWNLOAD_TEMP_PATH, new_exe_name)}"')
With the Followings:
'''
Popen([new_exe_name], shell=True,
creationflags=CREATE_NO_WINDOW | DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
关闭之前的程序后安装程序会继续正常运行
效果非常好
感谢@Obaskly 和@DerSchinken 的帮助!