我使用python制作了一个粗略的自动更新应用程序,并使用freeze-cx制作了exe文件。
首先,应用程序检查firebase服务器上是否有最新版本的文件,如果有则下载zip文件。该应用程序解压缩并覆盖文件。
this_file_path = sys.executable if getattr(sys, 'frozen', False) else __file__
path_here = str(Path(this_file_path).parent.absolute())
storagePath = '/version/File'+ver_recent+'.zip'
storage.child(storagePath).download(path='', filename=path_here+'/File.zip')
file_name = path_here+'/File.zip'
output_dir = path_here+"\\"
format = "zip"
messagebox.showinfo('Update Ongoing', 'Downloading newest version is done. Extracting file to:'+output_dir)
shutil.unpack_archive(file_name, output_dir, format)
在这里,我的意图是我的应用程序覆盖文件夹中的所有组件。
我确认,如果我告诉我的应用程序覆盖其他文件夹中的文件,并且我看到其他人说这种机制是可能的。
但是,在运行程序时,它会吐出错误消息:
open(targetpath, 'wb') as target:
PermissionError: [Errno13] Permission denied: C\\Users\\bboyc\\Documents\\File_0142\\lib\\_asyncio.pyd
由于我对Python还是新手,我无法猜测确切的原因。我只是不明白为什么该文件拒绝被访问。
谁能告诉我发生了什么事或者我失踪了?当未运行的文件发生这种情况时,我成功覆盖了,所以我认为不是 _asyncio.pyd 文件的问题。
问题是我尝试替换当前正在运行的文件。我认为可以参考我主要写作中的链接来完成,但似乎并非如此。
我通过生成一个批处理文件解决了这个问题,该文件在临时文件夹中提取 zip 文件并关闭程序,覆盖文件,然后重新运行程序。
如何编写批处理文件是这样的:
def create_update_script(temp_dir, program_dir, restart_script):
update_script_path = Path(temp_dir) / "update.bat"
with open(update_script_path, 'w') as file:
file.write('@echo off\ntimeout /t 1 /nobreak > NUL\nxcopy /s /e /y "'+temp_dir+'\\*" "' +program_dir+'\\*"\ntimeout /t 1 /nobreak > NUL\nstart "" "'+str(restart_script)+'"\ndel "'+str(update_script_path)+'"')
return update_script_path
update_script_path = create_update_script(temp_dir, path_here, restart_script)
subprocess.Popen(["cmd", "/c", str(update_script_path)])
一切顺利。