How can I enable auto-updates in a Qt cross-platform application?
I love applications that are able to update themselves without any effort from the user (think: Sparkle framework for Mac). Is there any code/library I can leverage to do this in a Qt application, without having to worry about the OS details?
At least for Windows, Mac and user-owned Linux binaries.
I could integrate Sparkle on the Mac version, code something for the Linux case (only for a standalone, user-owned binary; I won't mess with distribution packaging, if my program is ever packaged), and find someone to help me on the Windows side, but that's horribly painful.
Solution 1:
It is not a complete solution, but a cross-platform (Windows, Mac, Linux) tool for creating packages for auto-updates and installing them is available at https://github.com/mendeley/Update-Installer. This tool does not deal with publishing updates or downloading them.
This was written for use with a Qt-based application but to make the update installer small, standalone and easy to build, the installer uses only standard system libraries (C++ runtime, pthreads/libz/libbz2 on Linux/Mac, Win32 API on Windows, Cocoa on Mac, GTK with fallback on Linux). This simplifies delivering updates which include new versions of Qt and other non-system libraries that your application may depend on.
Before considering this though, I would suggest:
- If you are only building for two platforms, consider using standard and well-tested auto-update frameworks for those platforms - eg.
Sparkle
on Mac,Google's Omaha
on Windows or auto-update systems built into popular install frameworks (eg. InstallShield). I haven't tried BitRock. - On Mac, the Mac App Store may be a good option. See https://bugreports.qt.io/browse/QTBUG-16549 though.
- On Linux, consider creating a .deb package and a simple repository to host it. Once users have a repository set up, the system-wide software update tools will take care of checking for and installing new releases. The steps for setting up a new repository however are too complex for many new Ubuntu/Debian users. What we did, and also what Dropbox and Google have done, is to create a .deb package which sets up the repository as part of the package installation.
A few other notes on creating an updater:
- On Windows Vista/7, if the application is installed system-wide (eg. in C:\Program Files\$APPNAME) your users will see a scary UAC prompt when the updater tries to obtain permissions to write to the install directory. This can be avoided either by installing to a user-writable directory (I gather that this is what Google Chrome does) or by obtaining an Authenticode certificate and using it to sign the updater binary.
- On Windows Vista/7, an application .exe or DLL cannot be deleted if in use, but the updater can move the existing .exe/DLL out of the way into a temporary directory and schedule it for deletion on the next reboot.
- On Ubuntu, 3rd-party repositories are disabled after distribution updates. Google works around this by creating a cron-job to re-add the repository if necessary.
Solution 2:
Shameless plug: Fervor, a simple multiplatform (Qt-based) application autoupdater inspired by Sparkle.
Solution 3:
Shameless plug: this a relatively old question, but I thought that it may be useful to mention a library that I created recently, which I named "QSimpleUpdater". Aside from notifying you if there's a newer version, it allows you to download the change log in any format (such as HTML or RTF) and download the updates directly from your application using a dialog.
As you may expect from a Qt project, it works on any platform supported by Qt (tested on Windows, Mac & Linux).
Links:
- Website
- GitHub repository
Screenshot:
Solution 4:
Though it works a bit differently than Sparkle, BitRock InstallBuilder contains an autoupdater written in Qt that can be used independently (disclaimer, I am the original BitRock developer). It is a commercial app, but we have free licenses for open source projects.
Solution 5:
I've developed an auto-updater library which works beautifully on Mac OS X, Linux and pretty much every Unix that allows you to unlink a file while the file is still open. The reason being that I simply extracted the downloaded package on top of the existing application. Unfortunately, because I relied on this functionality, I ran into problems on Windows as Windows does not let you unlink an open file.
The only alternative I could find is to use MoveFileEx with the replace on reboot flag, but that is awful.
However, renaming the working directory of the application works on Windows 7 and Windows XP. I haven't tried Windows Vista yet.