AUpdater#
Updater class.
Header: | #include <AUI/Updater/AUpdater.h> |
CMake: | aui_link(my_target PUBLIC aui::updater) |
Detailed Description#
Experimental Feature
This API is experimental. Experimental APIs are likely to contain bugs, might be changed or removed in the future.
AUpdater follows a strategy pattern, i.e., you are excepted to call its functions, but the behavior and conditions are up to you.
Refer to aui::updater
for the update process overview.
Public Types#
InstallCmdline#
struct AUpdater::InstallCmdline
Data required to launch installation child process.
Field | Description |
---|---|
APath installerExecutable
|
Absolute path to installer executable. By default, installerExecutable is a copy of your application executable. The installation process is triggered via installerArguments. |
AVector<AString> installerArguments
|
Arguments passed to installer. |
GetInstallationDirectoryContext#
struct AUpdater::GetInstallationDirectoryContext
Context for AUpdater::getInstallationDirectory
Field | Description |
---|---|
APath selfProcessExePath
|
Self process exe. Typically AProcess::self()->getPathToExecutable() .
|
APath updaterDir
|
Updater dir. Typically parent of selfProcessExePath. |
APath originExe
|
The path to executable who invoked the installation process. Typically full path to the original exe to replace. |
StatusIdle#
struct AUpdater::StatusIdle
Idling.
Empty structure.
StatusCheckingForUpdates#
struct AUpdater::StatusCheckingForUpdates
Checking for updates.
Empty structure.
StatusDownloading#
struct AUpdater::StatusDownloading
Downloading state.
Empty structure.
StatusNotAvailable#
struct AUpdater::StatusNotAvailable
AUpdater::isAvailable() evaluated to false.
Empty structure.
StatusWaitingForApplyAndRestart#
struct AUpdater::StatusWaitingForApplyAndRestart
Waiting to applyUpdateAndRestart call state.
Field | Description |
---|---|
InstallCmdline installCmdline
|
Public fields and Signals#
mAsync#
AAsyncHolder mAsync
Holder for async operations.
status#
AProperty<std::any> status
State of the updater.
Status of the AUpdater to observe from outside, i.e., by UI.
status
is updated in UI thread only.
status
is designed in such a way the user can use their own custom status types or any of predefined ones:
AUpdater::StatusIdle
AUpdater::StatusCheckingForUpdates
AUpdater::StatusDownloading
AUpdater::StatusWaitingForApplyAndRestart
AUpdater::StatusNotAvailable
These statuses might be set by AUpdater itself.
Typical observer of status is a UI projection displaying its value. You can even display controls in it:
CustomLayout {} & mUpdater->status.readProjected([&updater = mUpdater](const std::any& status) -> _<AView> {
if (std::any_cast<AUpdater::StatusIdle>(&status)) {
return _new<AButton>("Check for updates").connect(&AView::clicked, AUI_SLOT(updater)::checkForUpdates);
}
if (std::any_cast<AUpdater::StatusCheckingForUpdates>(&status)) {
return Label { "Checking for updates..." };
}
if (auto downloading = std::any_cast<AUpdater::StatusDownloading>(&status)) {
return Vertical {
Label { "Downloading..." },
_new<AProgressBar>() & downloading->progress,
};
}
if (std::any_cast<AUpdater::StatusWaitingForApplyAndRestart>(&status)) {
return _new<AButton>("Apply update and restart")
.connect(&AView::clicked, AUI_SLOT(updater)::applyUpdateAndRestart);
}
return nullptr;
}),
Public Methods#
applyUpdateAndRestart#
Deploy the downloaded update.
Basically about replacing files (no network operations will be performed).
Requires AUpdater::status
= StatusWaitingForApplyAndRestart, otherwise has no effect.
Terminates current process with std::exit(0)
Debugging update deployment#
You can locate update deployment logs by locating deployment process id (pid). The PID is printed by this function:
Log files location are printed in the beginning of every AUI-based programs (if they use ALogger):
You can now locate the log file by using subprocess' PID printed earlier:
cat /tmp/aui.3708325.log
[06:49:33][UI thread][Logger][INFO]: Log file: /tmp/aui.3708325.log
[06:49:33][UI thread][AUpdater][INFO]: --aui-updater-wait-for-process: 3707546 exited with 0
[06:49:33][UI thread][AUpdater][INFO]: deploying update: /tmp/__aui_update_example_app/download -> /home/...
[06:49:33][UI thread][AUpdater][ERR]: Can't deploy update, trying to launch original: ...
- at 0x5555558f3aae aui_entry(AStringVector const&)(main.cpp:9)
- at 0x5555556b0028 aui_main(int, char**, int (*)(AStringVector const&))(OSDesktop.cpp:160)
- at 0x7ffff7261248(?:0)
- at 0x7ffff726130b(?:0)
- at 0x555555654195(?:0)
Caused by: (AIOException) AFileOutputStream: could not open /home/...: Text file busy
- at 0x5555556c0443 aui::impl::lastErrorToException(AString)(ErrorToExceptionImpl.cpp:21)
- at 0x55555568ec97 AFileOutputStream::open(bool)(AFileOutputStream.cpp:67)
- at 0x55555568ed44 AFileOutputStream::AFileOutputStream(AString, bool)(AFileOutputStream.cpp:24)
- at 0x5555556964a2 APath::copy(APath const&, APath const&)(APath.cpp:291)
- at 0x555555641585 AUpdater::deployUpdate(APath const&, APath const&)(AUpdater.cpp:267)
- at 0x5555558fb2ff AUpdater::handleStartup(AStringVector const&)(AUpdater.cpp:76)
- at 0x5555558f3aae aui_entry(AStringVector const&)(main.cpp:9)
- at 0x5555556b0028 aui_main(int, char**, int (*)(AStringVector const&))(OSDesktop.cpp:160)
- at 0x7ffff7261248(?:0)
- at 0x7ffff726130b(?:0)
- at 0x555555654195(?:0)
checkForUpdates#
Sets status
to AUpdater::StatusCheckingForUpdates
and calls AUpdater::checkForUpdatesImpl, implemented
by user.
Requires AUpdater::status
= StatusIdle, otherwise has no effect.
checkForUpdatesImpl#
virtual AFuture<void> AUpdater::checkForUpdatesImpl()
Check for updates user's implementation.
cleanupUnpackedUpdateDirBeforeDownloading#
called by AUpdater::downloadUpdate before downloading update to cleanup AUpdater::getUnpackedUpdateDir() dir.
deployUpdate#
Deploys update by recursively copying (moving) files from source dir to destination dir.
Called in newly downloaded executable.
downloadAndUnpack#
Typical download and unpack implementation.
Called by downloadUpdateImpl. Updates AUpdate::status progress.
downloadUpdate#
Sets status
to AUpdater::StatusDownloading
and calls AUpdater::downloadUpdateImpl, implemented by user.
An implementation might expect to checkForUpdates to be called first.
downloadUpdateImpl#
Performs update delivery to the specified directory.
- Arguments
unpackedUpdateDir
location to unpack an update to.
Typically implemented as download to temporary dir and unpacking the archive to the specified unpackedUpdateDir.
Unpack your application files to unpackedUpdateDir
. AUpdater is responsible for cleaning this dir in the
future.
getInstallationDirectory#
virtual APath AUpdater::getInstallationDirectory(const GetInstallationDirectoryContext& context)
Retrieves installation directory based on given context.
Default implementation guesses installation directory based on
getModuleName#
virtual AString AUpdater::getModuleName()
Returns a module name of your (your_app_name or your_app_name.exe, without a leading path).
Default implementation determines module name using AProcess::self().
The module name is used to construct temporary directory and locate an executable in a downloaded portable.
getTempWorkDir#
virtual APath AUpdater::getTempWorkDir()
Working directory for AUpdater. By default, points to some path in TEMP.
getUnpackedUpdateDir#
virtual APath AUpdater::getUnpackedUpdateDir()
The path where the update is unpacked to.
The dir persists between different launches.
handlePostUpdateCleanup#
Performs post update cleanup routines.
Default implementation deletes AUpdater::getUnpackedUpdateDir() dir.
handleStartup#
virtual void AUpdater::handleStartup(const AStringVector& applicationArguments)
Performs a pre-application AUpdater routine.
- Arguments
applicationArguments
arguments to your program.
The arguments starting with --aui-updater
are should be ignored by your application.
Performs autoupdate-specific routines on startup of your application. In best scenario, this function should be called by your application as early as possible.
This function might terminate current process with std::exit(0), in case of performing autoupdate routines.
This function will attempt to restore InstallCmdline state (StatusWaitingForApplyAndRestart) via AUpdater::loadInstallCmdline. If the latter succeeds, AUpdate::triggerUpdateOnStartup is called to perform on-startup update.
This function handles following arguments to your application:
- --aui-updater-origin
-
- --aui-updater-wait-for-process
- maps to AUpdater::handleWaitForProcess()
that instructs AUpdater to wait
the specified process to finish before processing next argument(s).
- --aui-updater-cleanup
- maps to AUpdater::handlePostUpdateCleanup()
and returns control flow to normal
execution of your application (last updating step)
- --aui-updater-failed
- reports last error occurred while update deployment. See AUpdater::getLastDeploymentError().
Refer to aui::updater
for update process overview.
handleWaitForProcess#
Handles --aui-updater-wait-for-process.
injectWaitForMyPid#
Injects --aui-updater-wait-for-process=THIS_PROCESS_PID as the first argument.
isAvailable#
Checks that updater functionality is available.
For cases when AUpdater is available see aui::updater
loadInstallCmdline#
virtual AOptional<InstallCmdline> AUpdater::loadInstallCmdline()
Restores install command line state, if any.
AUpdater::handleStartup will try to restore the state via loadInstallCmdline. If InstallCmdline is successfully restored, AUpdater immediately triggers update routine with triggerUpdateOnStartup which exits the application.
The implementation must ensure that subsequent startups would not trigger on-startup update to avoid endless loops in case of failure, i.e, by deleting a file.
makeDefaultInstallationCmdline#
Constructs InstallCmdline with default arguments.
By default, installerExecutable is a copy of your application executable. The installation process is triggered via special arguments in installerArguments.
reportDownloadedPercentage#
Being called by downloadUpdateImpl, reports download percentage to status
.
Requires AUpdater::status
= StatusDownloading, otherwise has no effect. Updates the value in UI thread.
reportReadyToApplyAndRestart#
Dumps InstallCmdline to temporary download directory, indicating that an update is ready to install. Updates status accordingly.
saveCmdline#
Saves install command line to restore state when application is restarted.
triggerUpdateOnStartup#
Triggers update routine.
The function is called by AUpdater::handleStartup. If triggerUpdateOnStartup succeeds, it should terminate execution of the current process.
Requires AUpdater::status
= StatusWaitingForApplyAndRestart.
If you'd like to disable applying downloaded update on startup, stub this function.