自更新 py2exe/py2app 应用程序
我维护一个基于 PyQt 的跨平台应用程序,可以在 Linux Mac 和 Windows 上运行。
Windows 和 Mac 版本使用 py2exe 和 py2app 进行分发,这会生成相当大的包(~40 MB)。
我想添加一个“自动更新”功能,基于补丁来限制下载大小:
- 在http服务器上检查新版本
- 下载更新到最新版本所需的补丁
- 应用补丁列表并重新启动应用程序
我有一些问题:
- 由于打开的文件被锁定且无法覆盖,因此更新 Windows 应用程序的首选方法是什么?
- 我该如何准备和应用补丁? 也许使用 bsdiff/pspatch ?
[更新]
我做了一个简单的类来使用bsdiff制作补丁,其中正如其网站上所宣传的那样,非常高效:我的应用程序的两个 py2exe 版本(约 75 MB 未压缩)的差异会生成 44 kB 补丁! 对我来说足够小,我会坚持这种格式。
该代码位于 pyflu 的“更新”包中,这是一个小型 Python 代码库。
I maintain a cross platform application, based on PyQt that runs on linux mac and windows.
The windows and mac versions are distributed using py2exe and py2app, which produces quite large bundles (~40 MB).
I would like to add an "auto update" functionality, based on patches to limit downloads size:
- check for new versions on an http server
- download the patches needed to update to the last version
- apply the patches list and restart the application
I have some questions:
- what is the preferred way to update a windows application since open files are locked and can't be overwritten ?
- how do I prepare and apply the patches ? perhaps using bsdiff/pspatch ?
[update]
I made a simple class to make patches with bsdiff, which is very efficient as advertised on their site : a diff on two py2exe versions of my app (~75 MB uncompressed) produces a 44 kB patch ! Small enough for me, I will stick to this format.
The code is available in the 'update' package of pyflu, a small library of Python code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我不相信 py2exe 支持修补更新。 但是,如果您不将整个包捆绑到单个 EXE 中(py2exe 网站示例 -页面底部),您只需替换某些文件即可避免较小的更新,例如 EXE 文件。 这可以显着减少更新的大小。
您可以编写一个单独的更新程序应用,可以从应用程序内部下载/运行该应用程序。 此应用程序每次更新可能会有所不同,因为需要更新的文件可能会发生变化。
一旦应用程序启动更新程序,它将需要自行关闭,以便覆盖文件。 更新程序完成后,您可以让它在自行关闭之前重新打开应用程序。
I don't believe py2exe supports patched updates. However, if you do not bundle the entire package into a single EXE (py2exe website example - bottom of page), you can get away with smaller updates by just replacing certain files, like the EXE file, for example. This can reduce the size of your updates significantly.
You can write a separate updater app, which can be downloaded/ran from inside your application. This app may be different for every update, as the files that need to be updated may change.
Once the application launches the updater, it will need to close itself so the files can be overwritten. Once the updater is complete, you can have it reopen the application before closing itself.
我不知道补丁,但在 OS X 上,可可应用程序的“标准”是 Sparkle 。 基本上它是“appcasting”。 它每次都会下载完整的应用程序。 也许值得一看它以获取灵感。
我想在 OS X 上,您可能只需下载应用程序包的实际部分,其中包含您的特定代码(而不是打包的库等),并且该部分相当小并且易于在包中替换。
在 Windows 上,您可能可以通过不将应用程序捆绑到一个 exe 中来实现类似的技巧 - 从而让您更改实际已更改的文件。
我想你的实际 Python 代码将远小于 40Mb,所以这可能是正确的选择。
至于替换正在运行的应用程序,首先您需要找到它的位置,因此您可以使用 sys.executable 来为您提供一个起点,然后您可能可以分叉一个子进程来杀死父进程过程并让孩子进行实际的替换?
我目前正在玩一个小型 wxPython 应用程序,并且想知道这个问题。 我很想听听你的想法。
另外,压缩后你的应用程序有多大? 如果它压缩得很好,那么也许您仍然有能力发送整个内容。
I don't know about patches, but on OS X the "standard" for this with cocoa apps is Sparkle. Basically it does "appcasting". It downloads the full app each time. It might be worth looking at it for inspiration.
I imagine on OS X you can probably just download the actual part of your app bundle that contains your specific code (not the libs etc that get packaged in) and that'd be fairly small and easy to replace in the bundle.
On Windows, you'd probably be able to do a similar trick by not bundling your app into one exe - thus letting you change the one file that has actually changed.
I'd imagine your actual Python code would be much less than 40Mb, so that's probably the way to go.
As for replacing the running app, well first you need to find it's location, so you could use
sys.executable
to get you a starting point, then you could probably fork a child process to, kill the parent process and have the child doing the actual replacement?I'm currently playing around with a small wxPython app and wondering about exactly this problem. I'd love to hear about what you come up with.
Also how big is you app when compressed? If it compresses well then maybe you can still afford to send the whole thing.
现在已经 4 岁了,但是 Esky 怎么样?
This is 4 years old now, but what about Esky?
由于 py2exe 将应用程序的所有已编译模块放入 ZIP 文件中,因此您可以尝试通过创建一个从给定文件集更新该文件的脚本来更新该文件。
然后替换其余已更改的文件(如果有的话,应该很少)。
Since py2exe puts all of the compiled modules of your app into a ZIP file, you could try to update this file by creating a script that updates it from a given set of files.
Then replace the remaining files that have changed (which should be few, if any).
一篇旧文章,但我想我应该提到 pyupdater 和 pyinstaller。
它支持亚马逊和 scp。
根据最近的 github 帖子,未来他们计划支持免费替代品。
An old post, but I thought I'd mention pyupdater with pyinstaller.
It supports Amazon and scp.
In the future, according to recent github posts, they plan to support free alternatives.