Python shutdown.copytree:[WinError 32]该进程无法访问该文件,因为该文件正在被另一个进程使用

问题描述 投票:0回答:1

在 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,复制树将正常工作,不会出现错误。

有人有办法解决这个问题吗?谢谢!

python shutil atexit copytree
1个回答
0
投票

您的代码造成了死锁。

subprocess.run("updateloader.exe")

file1.exe
应用程序正在启动一个子进程,其任务是替换父应用程序。尝试执行任务时,
file1.exe
进程正在等待退出,因此可执行文件已打开且无法替换。

要执行更新,需要一个独立的进程。 Microsoft 文档 指出创建分离进程的标志是

0x00000008

DETACHED_PROCESS = 0x00000008

pid = subprocess.Popen(["updateloader.exe"], creationflags=DETACHED_PROCESS).pid
© www.soinside.com 2019 - 2024. All rights reserved.