|
| 1 | +# Porting guide |
| 2 | +The following guide will help you to convert an application that uses version 2.1.5 of the library to the new |
| 3 | +version 3.0.0. This was a major update and thus introduces code changes that have to be manually adjusted. The |
| 4 | +update mostly added features and changed the internal structure, but existing classes had their APIs cleaned up |
| 5 | +as well. |
| 6 | + |
| 7 | +> This guide will only handle changes to existing APIs, i.e. the core and widgets modules with the QtIFW plugin. Any other new additions are not referenced here. |
| 8 | +
|
| 9 | +## General API changes |
| 10 | +The core change from 2 to 3 are two main things. First is, that the library now supports more than just QtIFW. It |
| 11 | +now supports 6 different backends, in the form of plugins. This does not really matter for this guide. Only how you |
| 12 | +deploy the application has sligthly changed. Second, the module now allows more sofisticated installations. It can |
| 13 | +run installations in parallel and track their progress. This too, does not really affect QtIFW, as it only launches |
| 14 | +an external installer. However, on Linux and macOs, it is now possible to run the maintenancetool in parallel to the |
| 15 | +running application. |
| 16 | + |
| 17 | +Information about the plugin for QtIFW and it specialities can be found on the |
| 18 | +@ref qtautoupdater_backends "backends page" in the documentation. |
| 19 | + |
| 20 | +## Porting QtAutoUpdaterCore |
| 21 | +The following changes have been made to the core module. They are mostly cosmetic changes, i.e. changing how the |
| 22 | +API is presented. The are listed in the following ordered by classes. |
| 23 | + |
| 24 | +### Changes to UpdateInfo |
| 25 | +The UpdateInfo class has been moved out of Updater is now called QtAutoUpdater::UpdateInfo. Is has been converted to |
| 26 | +a fully fledged gadget. Instead of members, it has now equally named properties with get and set accessors. In |
| 27 | +addition, there are comparators and functions to use them as key to hashes. |
| 28 | + |
| 29 | +The `size` member has been completly removed, as part of the generalization that happend to the library. You can |
| 30 | +still access it, via the newly added `data` property: |
| 31 | +@code{.cpp} |
| 32 | +auto size = info.data()["size"].toULongLong(); |
| 33 | +@endcode |
| 34 | +The size is also the secondary info property for QtIFW. See QtAutoUpdater::UpdaterBackend::secondaryInfo. |
| 35 | + |
| 36 | +### Changes to AdminAuthoriser |
| 37 | +This class has always been more of a side-class. Instead of a class it is now a namespace and provides two methods. |
| 38 | +The `hasAdminRights` method has been removed and replaced with QtAutoUpdater::AdminAuthoriser::needsAdminPermission. |
| 39 | +That method instead tries to guess if the execution of the given executable needs an elevation of rights first, or |
| 40 | +if it can be executed in the current context. `executeAsAdmin` has not been changed, but now allows you to add the |
| 41 | +working directory as parameter (ignored on macOs). |
| 42 | + |
| 43 | +### Changes to Updater |
| 44 | +As the primary class of the module, this class has changed the most. While is functionality stayed the same - to |
| 45 | +check for updates and launch the installation - the API has been improved and generalized. Also, since now plugins |
| 46 | +are used, the configuration is different |
| 47 | + |
| 48 | +#### Creation |
| 49 | +Instead of creating it via the constructor, there is now a factory method - QtAutoUpdater::Updater::create. It |
| 50 | +takes a backend and a configuration and creates the updater using that backend from it. To create an updater with a |
| 51 | +maintenancetool, use the following code: |
| 52 | + |
| 53 | +@code{.cpp} |
| 54 | +auto updater = QtAutoUpdater::Updater::create("qtifw", { |
| 55 | + {"path", pathToTheMaintenancetool} |
| 56 | +}, parent); |
| 57 | +@endcode |
| 58 | + |
| 59 | +To create an updater instance with the default path, simply leave out the configuration. There are a few other |
| 60 | +parameters you can use here. There are partially explained in other parts of this guide - but you can also take a |
| 61 | +look at @ref qtautoupdater_backends_qtifw. You can also use a configuration file. It would look like this: |
| 62 | + |
| 63 | +@code{.ini} |
| 64 | +[General] |
| 65 | +backend=qtifw |
| 66 | +path=pathToTheMaintenancetool |
| 67 | +... |
| 68 | +@endcode |
| 69 | + |
| 70 | +#### Status report |
| 71 | +The updater now uses the QtAutoUpdater::Updater::state property to track the state. The |
| 72 | +QtAutoUpdater::Updater::running property stayed, but is simply a wrapper around that state to simplify it down to |
| 73 | +the information, whether the updater is doing something or not. All the accessors directly linked with the |
| 74 | +maintenancetool have been removed. This includes the members `maintenanceToolPath`, `exitedNormally`, `errorCode` |
| 75 | +and `errorLog`. This information is now logged internally and cannot be accessed anymore. |
| 76 | + |
| 77 | +#### Checking for updates |
| 78 | +The method to start an update check stayed the same: QtAutoUpdater::Updater::checkForUpdates - but it now returns |
| 79 | +void instead of bool, as the state can be used to track the progress. The QtAutoUpdater::Updater::progressChanged |
| 80 | +signal has been added to provide a more detailed progress for supported plugins. QtIFW does not provide those |
| 81 | +details, so you can ignore the signal. Once the update check is done, the QtAutoUpdater::Updater::checkUpdatesDone signal is still beeing emitted, but it |
| 82 | +now only has the status as parameter instead of two booleans. The update details can still be accessed via the |
| 83 | +QtAutoUpdater::Updater::updateInfo property. |
| 84 | + |
| 85 | +It is also possible to add additional arguments to the update check run of the maintenancetool. To do so, use the |
| 86 | +`extraCheckArgs` in the configuration to specify those arguments: |
| 87 | + |
| 88 | +@code{.code} |
| 89 | +{ |
| 90 | + {"extraCheckArgs", "someArg=tree"} |
| 91 | +} |
| 92 | +@endcode |
| 93 | + |
| 94 | +#### Installing updates |
| 95 | +The method to start an installation has been renamed from `runUpdaterOnExit` to QtAutoUpdater::Updater::runUpdater |
| 96 | +and now takes two arguments to specify how updates should be installed. There are various options, but only two of |
| 97 | +them are viable: |
| 98 | + |
| 99 | +- QtAutoUpdater::Updater::runUpdater(QtAutoUpdater::Updater::InstallModeFlag::OnExit) |
| 100 | +- QtAutoUpdater::Updater::runUpdater(QtAutoUpdater::Updater::InstallModeFlag::Parallel) |
| 101 | + |
| 102 | +The first one works for all platforms and exhibits the same behaviour as the old version. It schedules the installer |
| 103 | +to be executed on exit of the running application. The second one only works on Linux and macOs and launches the |
| 104 | +installer immediatly, in parallel to the running application. For this variant, you can track the installation via |
| 105 | +the state and by waiting for the QtAutoUpdater::Updater::installDone signal. |
| 106 | + |
| 107 | +If you want to specify additional arguments to the installation, use the configuration. The following parameters |
| 108 | +can be added. `silent` will make the updater run in background, `extraInstallArgs` allows you to pass any additional |
| 109 | +arguments you desire to the installer and `runAsAdmin` can be used to specify if the installer should be run as |
| 110 | +admin or not. Leaving that one out will make the backend use the QtAutoUpdater::AdminAuthoriser to guess the |
| 111 | +correct value. The code below shows how the old constants are mapped to parameters in the configuration: |
| 112 | + |
| 113 | +@code{.code} |
| 114 | +// NormalUpdateArguments |
| 115 | +{} |
| 116 | +// PassiveUpdateArguments |
| 117 | +{ |
| 118 | + {"extraInstallArgs", "skipPrompt=true"} |
| 119 | +} |
| 120 | +// HiddenUpdateArguments |
| 121 | +{ |
| 122 | + {"silent", true} |
| 123 | +} |
| 124 | +@endcode |
| 125 | + |
| 126 | +#### Other changes |
| 127 | +The remaining changes are mostly stuff that has to do with the new plugin architecture and other small additions. |
| 128 | +Read the documentation for more details. Scheduling update checks is also still possible and now even supports use |
| 129 | +of the std::chrono classes. |
| 130 | + |
| 131 | +### Added classes |
| 132 | +The remaining changes to the module are mostly added classes that have to do with the new plugin architecture. |
| 133 | +Again, check the documentation for more details about these classes. |
| 134 | + |
| 135 | +## Porting QtAutoUpdaterGui |
| 136 | +The first thing to say here is, that the module has been renamed. It is now called *QtAutoUpdaterWidgets*, as it |
| 137 | +only creates a widgets GUI. For QML, there now is the `de.skycoder42.QtAutoUpdater.Quick` module you can import and |
| 138 | +use. Refer to the documentation of that namespace and the README for more details on how to use it. There haven't |
| 139 | +been any big changes functionality wise to this module. It still uses the controller to show a GUI and provides the |
| 140 | +UpdateButton as a dynamic button. However, the way these classes are used has changed and adjusted to the changes |
| 141 | +in the core module. No classes have been added or removed. |
| 142 | + |
| 143 | +### Changes to UpdateController |
| 144 | +The controllers API has been changed quite a bit. A lot of functionality that was duplicated from the internally |
| 145 | +used updater has been removed, as it can now be completly controlled via the updater. The GUIs that are shown by |
| 146 | +the controller however have not been changed. |
| 147 | + |
| 148 | +#### Construction and window affiliation |
| 149 | +Instead of using a maintenancetool, you now have to create the controller by passing it an updater. The controller |
| 150 | +does not take ownership of the updater, which is why the parenting has been united. If you create the controller |
| 151 | +with a QWidget as parent, all windows will be parented to that widget as well. If any other QObject is used as |
| 152 | +parent, the windows will be parentless toplevel windows instead. If the controller gets destroyed early, the updater |
| 153 | +stays alive and can still trigger an installer on exit. Thus, it is recommended to parent the controller correctly. |
| 154 | + |
| 155 | +In addition, the controller will now only show the GUIs if the parent window is visible (or minimized). A windows |
| 156 | +counts as visible even if hidden behind other windows or on another desktop. This allows you to add multiple |
| 157 | +controllers to different GUIs of your application, without the interferring, as long as only one of those windows |
| 158 | +is visible at a times. |
| 159 | + |
| 160 | +Finally, the QtAutoUpdater::UpdateController::createUpdateAction has been made static, the the action only requires |
| 161 | +a reference to an updater, not to the controller anymore. Otherwise, the action is still the same. It will however |
| 162 | +call QtAutoUpdater::Updater::checkForUpdates instead of using a controller, which means it is not possible to have |
| 163 | +an action with asklevel anymore. Any other level still works, as explained in the next section. |
| 164 | + |
| 165 | +#### Auto attachment to updaters |
| 166 | +Unlike before, the controller now "attaches" to the updater and can show a GUI in any state of the update check. If |
| 167 | +you for example create a controller while already checking for updates, there won't be a progress, but as soon as |
| 168 | +the check has finished, a result dialog will be shown (if enabled by display level). |
| 169 | + |
| 170 | +Because of this change, the `running` property of the controller has been removed. Use the updater instead to check |
| 171 | +if it is running or not. |
| 172 | + |
| 173 | +#### Setting the display level and running the controller |
| 174 | +Another change has been made to the display level handling. The display level is now a property, |
| 175 | +QtAutoUpdater::UpdateController::displayLevel. This property can be set and changed even during a running update |
| 176 | +check and takes effect as soon as the next dialog is shown. It is know global for all checks run via this |
| 177 | +controller. It is still possible to pass the level to the QtAutoUpdater::UpdateController::start method, but this |
| 178 | +will only set the property and then call `start` without any parameters. |
| 179 | + |
| 180 | +To run the controller, you should still call `start`, as it will show the ask dialog if wished before checking for |
| 181 | +updates. However, it is also possible to use QtAutoUpdater::Updater::checkForUpdates instead, as the controller is |
| 182 | +attached to the updater. This will work for all levels but the ask level, as the ask dialog will never be shown when |
| 183 | +an update check is started via the updater. |
| 184 | + |
| 185 | +Use the properties and signals of the QtAutoUpdater::Updater to track the progress. All such methods have been |
| 186 | +removed from the controller, as they are not needed there anymore. |
| 187 | + |
| 188 | +#### Removed members |
| 189 | +There are quite a few properties and methods that have been removed. Those have been mostly removed because the |
| 190 | +same functionality is already beeing provided by the underlying updater. The removed members are: |
| 191 | +`maintenanceToolPath`, `running`, `runAsAdmin`, `updateRunArgs`, `scheduleUpdate` and `cancelScheduledUpdate`. |
| 192 | + |
| 193 | +In the GUI, the run as admin checkbox has been removed. You should get this information programatically, and not |
| 194 | +by prompting the user, as the user typically has no clue about this. You can still specify it, by using the |
| 195 | +`runAsAdmin` configuration value. |
| 196 | + |
| 197 | +### Changes to UpdateButton |
| 198 | +The update button has seen changes similar to the controller. The main difference is, that it now only needs an |
| 199 | +updater instead of a controller, and that it supports a more sofisticated UI, including a state that is shown while |
| 200 | +installing parallel updates for Linux or macOs. The rest of it's GUI however has stayed the same. |
| 201 | + |
| 202 | +The fact that the button now uses an QtAutoUpdater::Updater only also means, that there is no display level anymore. |
| 203 | +Again, this is not problematic as any controller will automatically show required GUIs, even if completely detached |
| 204 | +from the button, as long as they use the same updater. |
| 205 | + |
| 206 | +Another thing that changed is, that you can now trigger an installation via the button, if updates are available. |
| 207 | +The QtAutoUpdater::UpdateButton::mode property controlls whether this is possible and how the button operates in |
| 208 | +general. If allowed and a user triggers the installation, the QtAutoUpdater::UpdateButton::installMode and |
| 209 | +QtAutoUpdater::UpdateButton::installScope properties are used as arguments for the |
| 210 | +QtAutoUpdater::Updater::runUpdater method call. |
| 211 | + |
| 212 | +## Final remarks |
| 213 | +As you can see from this guide, there have been quite a few changes. Most of them however are nothing more then |
| 214 | +sligthly more complex refactorings. Using this document you should be able to easily port any application from the |
| 215 | +old to the new version. If you however still have some questions, simply use the |
| 216 | +[GitHub Issues](https://github.com/Skycoder42/QtAutoUpdater/issues) to ask for help. I am aware that such a change |
| 217 | +can be challenging and I am always willing to provide any help I can. |
| 218 | + |
| 219 | +## Examples |
0 commit comments