PolyMC
PolyMC copied to clipboard
Implement Windows Updater
Role
To update polymc
Suggestion
We should have a compile option like DLauncher_updater_enable which would add an update button which would download the latest platform build.
Benefit
Manually installed packages would be easier to update. Especially for non-techy pepole
This suggestion is unique
- [X] I have searched the issue tracker and did not find an issue describing my suggestion, especially not one that has been rejected.
You may use the editor below to elaborate further.
Again, this should be optional and a compile flag. For packages that are in repositories, like the RPM Copr, Flathub package and probably soon others, they should use their update channels, not the button. This only for manually installed packages.
I think it would be fine to open a download like MMC does. Or AppImage/windows could automatically install the thing when the button is clicked
I agree this sounds like a great idea especially windows users.
Traditionally MultiMC provided just a small bootstrapping script for linux that downloaded the entire client. The client then self updated depending on the user's needs. This is all very similar to how steam works or even tor-launcher. This did however have the possibility of breaking due to incompatibilities(lets for example assume Qt Incompatibilities) and packaging the libraries PolyMC needs is a bad idea. It would however be a neat options for those that can run the latest version with no issues.
Traditionally MultiMC provided just a small bootstrapping script for linux that downloaded the entire client. The client then self updated depending on the user's needs.
This is all very similar to how steam works or even tor-launcher.
This did however have the possibility of breaking due to incompatibilities(lets for example assume Qt Incompatibilities) and packaging the libraries PolyMC needs is a bad idea. It would however be a neat options for those that can run the latest version with no issues.
This is probably better for windows and Mac as on Linux you have an actual package manager
I can see it being useful for appimage users though
This would not really work for AppImage, as you'd have to replace the entire file. We literally have no clue where the user put the AppImage, so we have no way to replace it.
For lin-nodeps, generally, we're only replacing the binary, not the libraries. Same goes for Mac and Windows.
This also reminds me that we need to setup notifications. If there's an RCE that got released or an otherwise serious bug, we need to let users know ASAP. This can be done simply with a small RSS feed.
You definitely could do it with appimages https://docs.appimage.org/packaging-guide/optional/updates.html Although honestly I feel like this is a stretch goal of some sorts
We should have a compile option like DLauncher_updater_enable which would add an update button which would download the latest platform build.
Do these build config options work for this, or is something else needed?
https://github.com/PolyMC/PolyMC/blob/fa870bc026b21aca7b3859cde8ba3f843a98e023/buildconfig/BuildConfig.h#L60-L75
https://github.com/PolyMC/PolyMC/blob/4899d3c4585d92ae46fcabf0a16695687bbce885/buildconfig/BuildConfig.cpp.in#L74-L76
If the updater is not needed, just don't set UPDATER_BASE.
It looks like upstream used a modified form of GoUpdate, and PolyMC still has that code: https://github.com/PolyMC/PolyMC/blob/develop/launcher/updater/GoUpdate.cpp
UPDATER_BASEis set to some URL (e.g.https://example.com/update/).- It gets channels from
UPDATER_BASE/[platform]/channels.json(e.g.https://example.com/update/osx64-5.15.2/channels.json). - Get versions within a channel from
UPDATER_BASE/[platform]/[channel]/index.json(e.g.https://example.com/update/osx64-5.15.2/stable/index.json). - Get information about the version from
UPDATER_BASE/[platform]/[channel]/[version_id].json(e.g.https://example.com/update/osx64-5.15.2/stable/3246.json), which includes a URL/md5/other attributes for every file to download and replace
And it seems like they used this tool to manage their GoUpdate repo: https://github.com/MultiMC/repoman2 (I didn't try it or look much into it though, so I'm not entirely sure how to use it)
Not sure how this works for AppImage though.
Edit: did some experimentation with repoman, and looks like this is how you use it:
- Clone the
repomanrepo andpip installit - Make a directory for your repo
/path/to/repo,cd /path/to/repo - Make a directory for files
/path/to/repo/files - Make a directory for each platform
/path/to/repo/lin64, etc. - Make a directory for each channel within each platform,
/path/to/repo/lin64/stable, etc. repoman create /path/to/repo https://example.com/update/ /path/to/repo/files https://example.com/update/files/to create the reporepoman add-platform [platform-name]to create the platforms (they must match the names of the directories you made)- Whenever you release a new version,
repoman push [platform] [channel] [vsn_id] [vsn_name] [vsn_path](vsn_pathis where the built program files are) - Upload the repo to somewhere people can download it
This could probably be automated with GitHub Actions/some other CI.
Wouldn't it work if released through winget on windows too? since winget is also available on windows 10.

I was about to make a small updater for myself but ended up getting caught by this, why is the building process not updating file version for windows builds?

See #644 — I accidentally wrote the commit hash as the version instead of the actual version number. I haven’t had time to get around to fixing this yet, unfortunately.
edit: actually maybe that specific one was fixed in #669, not sure
This will be partly implemented for 1.4.0, at least for macOS. We will probably bring a similar updating system to Windows as well.
For anyone who wants to try to implement the Windows updater, #479 provides some code to make that easier. It'll essentially boil down to the following:
- Link to the WinSparkle library
- Create a new subclass of
ExternalUpdater(https://github.com/PolyMC/PolyMC/blob/develop/launcher/updater/ExternalUpdater.h) and implement the pure virtual functions. (Note that some, e.g.setBetaAllowedaren't used at all; I only added those just in case, but a stub should work for those.) - Initialize the updater here (macOS example given): https://github.com/PolyMC/PolyMC/blob/ac8ee9f981ea509c04ce64d70a47429a1207e18e/launcher/updater/UpdateChecker.cpp#L28-L38
- Have GitHub Actions automatically sign the installer exe.
There may be a few considerations for the Windows updater:
- It needs to run the Windows installer (likely in silent mode). The following command line options for the installer should be helpful:
/S(silent mode),/NoShortcuts(do not install desktop/start menu shortcuts),/NoUninstaller(do not install an uninstaller, applies to portable installs) - It must install PolyMC in the same place it is currently installed from. Although this should happen automatically if the original installation was done with an installer (as the install location is stored in the registry), this may be more challenging if a user tries to update a portable installation.
Another thing we must consider(Windows): When we press the button to update and the installer runs in the background it don’t have to re-install/interact with the polyMc.exe because it will be running.
Another thing we must consider(Windows): When we press the button to update and the installer runs in the background it don’t have to re-install/interact with the polyMc.exe because it will be running.
Well it does need to interact with the existing PolyMC.exe in order to update it, the solution I've seen online is to rename the old exe then delete it on the next launch.
IIRC I had the installer close PolyMC if it is running before installation.
IIRC I had the installer close PolyMC if it is running before installation.
Oh yeah that also works because the installer is a separate program. Then there shouldn't be any problem with the exe file being currently in use.
IIRC I had the installer close PolyMC if it is running before installation.
Oh yeah that also works because the installer is a separate program. Then there shouldn't be any problem with the exe file being currently in use.
So if we do that the updater should re-open the .exe after closing it.
Leaving this here in case anyone wants to work on this:
https://packages.msys2.org/base/mingw-w64-winsparkle
On modern versions of windows, you have the winget package manager per-installed (or obtainable from the MS Store) which would make auto-update one command jsut like on Linux. So it would potentially be as easy as running winget upgrade -e --id PolyMC.PolyMC or whatever else you call it.
That doesn't work with, let's say, portable installs
Perhaps a temporary workaround could be to make a changelog popup similar to macOS, but upon clicking install it would simply open the installer exe download in the default browser. Would that be easier to implement?