Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Self updating py2exe/py2app application

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.

like image 857
Luper Rouch Avatar asked Apr 17 '09 13:04

Luper Rouch


2 Answers

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.

like image 136
Jason Coon Avatar answered Sep 18 '22 21:09

Jason Coon


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.

like image 24
John Montgomery Avatar answered Sep 18 '22 21:09

John Montgomery