Windows updater for app

Among most of all the software I have purchased, there is a really easy method to update the app that requires nothing more that an external app that does the work without any need to run an installer.

I am trying to add this functionality to my app.
when running my main app, it checks the server to see if the version on the \server is newer than the current… Then launches the update app and closes the main app.
With then update app, I can download the new version and unzip it into my appdata folder. So it’s sitting there as the complete exe file.
My problem is how to I replace my exe in program folder with this new one. I tried looking for shell commands to do it… all these other apps can do it - so It must be possible.
Any code snippet would be gladly appreciated.

I should mention that my main software, when it launches, send a text file to the app folder with the current working folder location of the app. I can access that from
f = New FolderItem(a, FolderItem.PathTypeNative)
a being the file location.
My main windows app is programmed in 2014 r 1 and it works really well. It’s a massive program and I spent 5 years in development and I don’t really want to jump through all the hoops to update it to ther xojo versions.
I do have 2019 r 1 which sorks quite well for the helper apps.
I also have a mac version - it works up until Ventura but Sonoma has absolutely broken it (thank you Apple for sucking).

Just use this: Kaju self-updater talk (v.2.x) - #5 by Kem_Tekinay


A running application cannot replace itself so you need a way to replace the app while it is not running and then relaunch the new version. You also have the problem that the Program Files folder will be read-only to standard users.

This is what we have been doing on macOS & MS-Windows for the past 15+ years:

1.The app downloads an update package which is a zip file containing the following:
a) The new version of the app / resources / libs.
b) An auto-update file replace helper app.
c) An auto-update restart app.

2.The main app unzips the package to a temporary folder.

3.The main app launches the auto-update file replace helper app as an administrator via the ShellExecuteExW Windows API and the runas verb. This app waits until it receives a signal from the main app before it does anything (on macOS we use AuthorizationMBS to launch the helper app elevated).

4.The main app launches the auto-update restart helper app via FolderItem.Launch. This app waits until it receives a signal from the auto-update file replace helper app before it does anything.

5.The main app writes a file to a temporary folder which is used to inform the auto-update file replace helper app that it is shutting down. The main app then quits.

6.Once the auto-update file replace helper app detects the temporary file it waits a couple of seconds and then performs the file copying / cleanup of redundant files.

7.Once the auto-update file replace helper app has finished it writes a file to a temporary folder which is used to inform the auto-update restart helper app that it has finished. The auto-update file replace helper app then quits.

8.Once the auto-update restart helper app detects the temporary file it then re-launches the new executable.

Some other points:

1.It is recommended you verify that the zip file hasn’t been tampered with before you replace anything as you don’t want to install anything malicious if your server is hacked.

2.We use two helper apps because if the auto-update file replace helper app re-launched the main app it would run with elevated privileges which you don’t want. This is why the auto-update restart helper app is launched via FolderItem.Launch as this means it runs as the same user as the main app.

3.You will need a way to cleanup your temporary folder.

4.You could possibly replace the helper apps with batch files. We didn’t go down this route because we wanted to use the same apps on macOS & MS-Windows and we also wanted to be able to change what tasks the auto-update process performed which wouldn’t be possible if the main app generated the batch files.

5.Windows will sometimes try to elevate executables when they are launched based on their filename. This caused us to tweak the names of our helper apps to avoid this. The section ‘Installer Detection Technology’ in this web page contains more information:
Understanding and Configuring User Account Control in Windows Vista | Microsoft Learn

TablePlus, a database editor I have a Windows copy of, just downloads the latest installer with the update window and launches that. I don’t see what’s so bad about that process, it handles all of the things listed under “My problem is” and doesn’t rely on the app constantly reporting its location.

Sam adopted this process (download installer and launch it) for App Wrapper, but Mac users get a little lost because they don’t use installers frequently and are surprised to find that is able to replace the app in-location (even the Trash).

I love the elegance of a self-updater for the user. Kaju is quite a bear to wrap your head around when you first get into it but it is a wonderful solution - the catch is I think it may use some features that xojo 2014 r1 doesn’t have. You may be able to finesse it to work solely as a helper app in xojo 2019 but now you’re distributing multiple versions of the framework and it’ll bloat your download size and add an extra layer of complexity.

I agree with @Tim_Parnell that running the installer is totally acceptable. The only catch is that you need to make sure your installer has logic to check if your application is currently running, and if so, either give the user the opportunity to quit or to automatically quit the app.

There are also third party solutions. Some that I’ve used in the past:

One more solution in this space that I think isn’t well known. If you’re a MBS user, Christian and team have extended Mac Sparkle to work for Windows:

This is now included with his Xojo plugins from at least a major version or two back. On the Windows side, if an update is found, it’ll download, quit your app and then autolaunch the installer.

1 Like