Creating a version updater on my .exe created with pyinstaller

54 views
Skip to first unread message

Deniz

unread,
Mar 27, 2020, 5:14:32 AM3/27/20
to PyInstaller

Hey guys, I wanted to create a version updater for my python program which would basically update the version of it to the most recent. As I give my .exe out to people, I want them to be able to click a button on the app which allows them to get the most recent update rather than manually searching online.

Does anyone have any advice or help building something like this? Even some scripts you have written before for this?

Steve Barnes

unread,
Mar 27, 2020, 7:27:05 AM3/27/20
to pyins...@googlegroups.com

Deniz,

 

Take a look at PyUpdater - https://www.pyupdater.org/ (even says it wouldn’t be possible without pyinstaller.

 

Steve Barnes

--
You received this message because you are subscribed to the Google Groups "PyInstaller" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyinstaller...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyinstaller/3615c7b6-1155-4a51-945f-0f22689f7cb0%40googlegroups.com.

Patrick Caruana

unread,
Mar 27, 2020, 5:23:06 PM3/27/20
to pyins...@googlegroups.com
I have recently started distributing a python program which had the same needs and I dealt with it in the following way. I'm not saying this is the best/only way, but just how I solved the problem:

1) use pyinstaller (NOT in single exe mode) to package the application - you will have an exe and lots of files/folders;
2) use Inno Setup to create a single exe windows installer for the pyinstaller-packaged application. It is this single exe that I distribute to users;
3) users install the exe following the inno setup wizard;
4) built into the logic of the app that I packaged in step 1, upon each startup the app queries a rest api that i have set up at www.domainname.com/update. The query returns a) the latest version of the app b) its encrypted checksum (more on this later) c) whether or not the update is mandatory.
5) the app compares its current version (from a variable in the app) to the latest version. If it is not the latest version, it downloads the latest version from a separate link (if the update is advertised as mandatory). If it is not mandatory, it presents a dialogue notifying of the update and asking whether the user wishes to download & install. The update file downloaded is also an innodb installer, rather than a pyinstaller exe (you can use the same exe for initial installs and for updates). The user sees a dialog showing the download progress bar. 
6) the app cryptographically verifies the integrity of the new version;
7) the app executes the exe with the following flags and immediately closes itself: "/SILENT", "/SP-", "/NOICONS"
8) these flags tell the inno setup to install automatically without asking the user to press any buttons and tells the setup to run the program and close itself after installation;
9) the progress bar the inno setup finishes, closes and the new version of the app opens;.

This is possible due to how inno setup works. Provided you keep the app key the same across different versions in the inno config file, if the user executes an installer for a newer version than they have inno setup will automatically overwrite the old version using the same installation directory. So each update is effectively delivering the latest version of the entire application and overwriting it. If your app is small like mine (less than 20mb) it is no problem serving the full app on each update.

The two disadvantages to this method are:

1) the user sees an inno setup wizard progress bar on each update (although they don't have to click anything on the setup - it starts automatically, runs automatically, closes automatically and the new version starts automatically) - also, you can install your own logo into the setup wizard to make it look more custom - but you can't escape that your "update" looks like an installation. 
2) windows raises a dialogue asking the user to confirm they want to run the update exe. Whilst it requires a click, after having watched the download progress bar it is obvious to users that they are being asked to approve the update installation. You can make this step more seamless by getting a windows code signing certificate and digitally signing your inno setup exes so at least you are properly identified. This step is the only user intervention in between running the app and ending up with a fully updated version starting up instead. 

Your app MUST verify the integrity of the downloaded update exe before it executes it. You do this with public/private key encryption. You get the checksum of the inno setup exe file. You then encrypt the checksum of the inno setup exe file using a private key. It is this encrypted checksum that you advertise on  www.domainname.com/update. When your client downloads the update exe, it tries to decrypt the encrypted checksum using the corresponding public key, which you presintall/ship with the previous version of your app. Once it decrypts the checksum it then does its own checksum on the exe and compares that result with the encrypted checksum. It only launches the update exe if they match, otherwise it throws a verification error.




On Fri, 27 Mar 2020 at 10:14, Deniz <dyuks...@gmail.com> wrote:

Hey guys, I wanted to create a version updater for my python program which would basically update the version of it to the most recent. As I give my .exe out to people, I want them to be able to click a button on the app which allows them to get the most recent update rather than manually searching online.

Does anyone have any advice or help building something like this? Even some scripts you have written before for this?

--

Patrick Caruana

unread,
Mar 29, 2020, 11:27:31 AM3/29/20
to pyins...@googlegroups.com
corrections my previous message to make it clearer:

The update file downloaded is also an inno setup installer, rather than a pyinstaller exe

Once it decrypts the checksum it then does its own checksum on the exe and compares that result with the decrypted checksum. 

to add:

- your rest api for the download exe should be https only (redirect http to https) 
- the public key used by the client to decrypt the checksum of the "future version inno setup exe"should be shipped with EVERY inno setup exe version that you distribute.
- you can instruct inno setup to install your app to a folder in the Program Files folder;
- you can also use inno setup to create a folder in the hidden ProgramData folder and use that to store the public key and any other files your app generates.
- you can use python tempfile to create a temporary folder in which to save the update exe. Make sure to delete this folder on application close or next startup as python does not clean up temp folders on the OS and this is left to you.





Reply all
Reply to author
Forward
0 new messages