Add a VERSION_INFO section to the executable's resource file specifying
the product name and description.
The organization is currently set as 'Mendeley Ltd' - other projects
will want to customize this.
When the produced executable is digitally signed, the product name
and description are shown in the UAC prompt asking for admin
permissions.
Mendeley Desktop <= 1.0 clients pass a relative path for the script argument but
run the updater from the directory containing the main application binary instead
of the package dir. The script argument, if relative, is therefore treated as
relative to the package directory.
Mendeley Desktop <= 1.0 clients set CurrentDir to the directory containing the main
application binary rather than the root of the install directory.
Change the parsing in UpdaterOptions and adjust the test accordingly.
* Embed the app icon in the updater executable on Mac and
use it as the application's icon.
* Transform the application from a background to a foreground app when the
Mac dialog is shown, so that the dock icon is shown.
* Forcibly give focus to the updater application so that the progress window
gains focus when it is shown.
There is a remaining glitch with the application where the icon briefly transforms
back from the app icon to the terminal icon as the application shuts
down. This presumably happens because the custom icon set on the NSApplication
is reset before the dock icon disappears.
The utimensat/futimens system calls were introduced in relatively recent Linux
kernels and are not available on Mac. Use utimes/futimes instead - since
microsecond precision is fine for our needs.
* Move class to get the app data directory to a new StandardDirs class.
* Setup an auto-release pool at the start/end of main() to catch objects
allocated outside of the updater dialog.
This is necessary so that Launch Services in OS X picks up changes
to the Info.plist file describing various aspects of the application.
See https://bugzilla.mozilla.org/show_bug.cgi?id=600098 for an example
of the kind of issue that failure to do this can lead to.
gtk_window_set_default_size() has no effect when the dialog
is marked as non-resizable with gtk_window_set_resizable(),
so the minimum size is instead achieved by setting a minimum width
on the progress bar.
* Centralize the error message text shown to the user in the event of a problem
installing the update in AppInfo::updateErrorMessage() and add a section
suggesting that the user should download a new copy from mendeley.com
Build the GTK dialog as a separate shared library which
is embedded into the main updater binary.
At runtime the updater extracts the shared library and attempts to load it.
If this succeeds, the GTK UI is used, otherwise the updater will fall
back to something else - currently a silent install.
The current update dialogs do not support retry/cancel - if a file
cannot be installed the update will just fail with an error and
any partial install will be reverted.
Following the change to FileOps::removeFile() to support 'removal'
of files that are in use in Windows, the cleanup of the updater's
temporary directory can be performed from the non-elevated updater
setup process once the main install process has returned.
This removes the --mode cleanup run mode in the updater.
* On Windows FileOps::removeFile() fails for updater.exe
since that file is in use by the current process.
Whilst it is not possible to remove the file whilst it
is in use, it can be moved or scheduled for deletion on reboot.
This commit changes FilesOps::removeFile() to simulate the
behavior of unlink() on Linux by moving in-use files to
a temporary directory and then scheduling for them to
be removed on restart.
There is no locking on the Log file so conflicting updater processes
may corrupt each others' entries - although in practice this has not
been a problem yet.
Previously the application was restarted from the main install process, which may have
been elevated. The main application must be started from a non-elevated updater/updater.exe
process otherwise the main app will inherit the elevated status from its parent.
* Modify ProcessUtils::runElevated() to return the status code of the process
* Change UpdateInstaller to run the main installation synchronously from the initial
updater process in the case where elevation is not required.
* Remove calls in main.cpp to relaunch the main application after the UI is closed.
Instead of moving the whole <update> section to an embedded <update-v3>
node, just use a different name for the <install> section since older
clients will ignore the new <packages> section.
For older clients:
* The <install> section lists the packages to download. This will exist
in addition to the <packages> section.
* The real <install> section listing the files to install is renamed to
<install-v3>
* Add WIN32 flag to add_executable() so that cmake generates a GUI application
* Add WinMain() entry point which converts the unicode command line arguments to ANSI and then calls the standard main() entry point.
The unit test continues to pass although I am not sure whether
converting command-line args from Unicode to ANSI will cause problems
with filenames passed on the command-line that contain non-ANSI
characters.
std::string::npos is defined as the unsigned type size_t but given a value of -1,
resulting in a warning when trying to compare an unsigned int with a size_t.
Fix this by declaring pos as a size_t.
* Fix ProcessUtils::runAsyncUnix() not returning a value
* Fix UpdateDialogGtk::updateRetryCancel() not returning a value
* Add missing includes in TestUpdaterOptions.cpp
* Fix unsigned/signed int comparisons
This prevents the dialog being closed part-way through update installation,
leaving the user unable to restart the application afterwards by clicking
the 'Finish' button.
UpdaterOptions::parse() will probably not have a need to modify its
arguments but for consistency with the declaration of main() it takes a char*,
so strdup() the strings.
In the event of a failed update, display the details in a message
box and allow the user to restart the old application once the
update has been reverted.
Details of the problem will also be written to the log file.
This prevents the user closing the dialog whilst the update is in
progress. Once the update has been installed, the user can click
the 'Finish' button to close the dialog and restart the application.
* Link the updater application with the Cocoa framework on Mac
* Construct a UI in code and display it when running the main install process.
Usually UIs on Mac are contained in a .nib file created with Interface Builder
but in this case the UI is created directly in code to meet the single-binary requirement,
although it may be possible to bundle the .nib into the binary itself.
* Add support for entries in the update script being marked with
a boolean <is-main-binary> attribute which is set to true for the main binary.
* In UpdateInstaller::restartMainApp(), look for the file marked with <is-main-binary>
and restart it after installation. With the current structure, this requires that
the main binary is included in the update, which has always been the case up till now.
If we find that we want to do updates that do not affect the main binary, the
<is-main-binary> attribute could be replaced with a <main-binary> string value
at the top of the XML file.
* Add optional GTK mode to the updater build. This pulls in a large number of extra dependencies,
but dependencies which should be fairly ubiquitous on Linux systems. If these dependencies prove
to be a problem we could look at providing an alternative, more basic UI and loading the appropriate
UI dynamically.
* Implement update progress dialog for GTK. The dialog needs visual polish but is functional.
* Set the --wait argument when launching new updater processes with the ID of the process to wait for.
* Add ProcessUtils::currentProcessId() utility method and PLATFORM_PID define