在 GitHub 上,我分享了一个 PyInstaller 生成的 exe 文件 (file1.exe)。这个想法是如果有新版本的文件,则自动更新过程。每次启动 file1.exe 时,程序都会检查 GitHub 上是否有新版本:
response = requests.get("https://api.github.com/repos/...releases/latest")
latestVersion = response.json()["tag_name"]
如果最新版本比正在运行的版本新,则会出现一个消息框,询问是否应应用更新。
我的想法是注册一个atexit函数,该函数运行另一个python脚本(updateloader.exe)作为子进程,从GitHub下载新版本并将其复制到file1.exe的文件夹中(覆盖file1.exe):
文件1:
...
atexit.register(updateloader)
sys.exit()
...
def updateloader():
subprocess.run("updateloader.exe")
updateloader.exe:
...
shutil.copytree("C:\Users\xy\Downloads\file1.exe", "C:\Users\xy\folder\file1.exe", dirs_exist_ok=True)
我得到的是这个异常: ('C:\Users\xy\Downloads ile1.exe'、'C:\Users\xy old ile1.exe'、'[WinError 32] 该进程无法访问该文件,因为该文件正在被另一个进程使用')。如果我手动关闭 file1.exe 并运行 updateloader.exe,复制树将正常工作,不会出现错误。
有人有办法解决这个问题吗?谢谢!
您的代码造成了死锁。
subprocess.run("updateloader.exe")
file1.exe
应用程序正在启动一个子进程,其任务是替换父应用程序。尝试执行任务时,file1.exe
进程正在等待退出,因此可执行文件已打开且无法替换。
要执行更新,需要一个独立的进程。 Microsoft 文档 指出创建分离进程的标志是
0x00000008
。
DETACHED_PROCESS = 0x00000008
pid = subprocess.Popen(["updateloader.exe"], creationflags=DETACHED_PROCESS).pid