On Ubuntu One we use BtiRock to create the packages for Windows. One of the new features I’m working on is to check if there are updates every so often so that the user gets notified. This code on Ubuntu is not needed because the Update Manger takes care of that, but when you work in an inferior OS…
Generate the auto-update.exe
In order to check for updates we use the generated auto-update.exe wizard from BitRock. Generating the wizard is very straight forward first, as with most of the BitRock stuff, we generate the XML to configure the generated .exe.
<autoUpdateProject>
<fullName>Ubuntu One</fullName>
<shortName>ubuntuone</shortName>
<vendor>Canonical</vendor>
<version>201</version>
<singleInstanceCheck>1</singleInstanceCheck>
<requireInstallationByRootUser>0</requireInstallationByRootUser>
<requestedExecutionLevel>asInvoker</requestedExecutionLevel>
</autoUpdateProject>
There is just a single thing that is worth mentioning about the above XML. The requireInstallationByRootUser is true because we use the generated .exe to check if there are updates present and we do not what the user to have to be root for that, it does not make sense. Once you have the above or similar XML you can execute:
{$bitrock_installation$}\autoupdate\bin\customize.exe" build ubuntuone_autoupdate.xml windows
Which generates the .exe (the output is in ~\Documents\AutoUpdate\output).
Putting it together with Twisted
The following code provides an example of a couple of functions that can be used by the application, first to check for an update, and to perform the actual update.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | import os import sys # Avoid pylint error on Linux # pylint: disable=F0401 import win32api # pylint: enable=F0401 from twisted.internet import defer from twisted.internet.utils import getProcessValue AUTOUPDATE_EXE_NAME = 'autoupdate-windows.exe' def _get_update_path(): """Return the path in which the autoupdate command is found.""" if hasattr(sys, "frozen"): exec_path = os.path.abspath(sys.executable) else: exec_path = os.path.dirname(__file__) folder = os.path.dirname(exec_path) update_path = os.path.join(folder, AUTOUPDATE_EXE_NAME) if os.path.exists(update_path): return update_path return None @defer.inlineCallbacks def are_updates_present(logger): """Return if there are updates for Ubuntu One.""" update_path = _get_update_path() logger.debug('Update path %s', update_path) if update_path is not None: # If there is an update present we will get 0 and other number # otherwise retcode = yield getProcessValue(update_path, args=('--mode', 'unattended'), path=os.path.dirname(update_path)) logger.debug('Return code %s', retcode) if retcode == 0: logger.debug('Returning True') defer.returnValue(True) logger.debug('Returning False') defer.returnValue(False) def perform_update(): """Spawn the autoupdate process and call the stop function.""" update_path = _get_update_path() if update_path is not None: # lets call the updater with the commands that are required, win32api.ShellExecute(None, 'runas', update_path, '--unattendedmodeui none', '', 0) |
With the above you should be able to easily update the installation of your frozen python app on Windows when using BitRock.
Read more
Latest Official Posts