TMS FNC App Update — Guides
Control file and remote version
The component reads a remote control file referenced by URL. The file contains the new version string and a list of files to download. AppInfo exposes the parsed metadata (what's new text, EULA, update message, and the informational URL) after a successful check.
Checking and applying updates
Call NewVersionAvailable to download the control file and compare it against the local installation, then call StartUpdate to download and apply the payload. DoUpdate combines the two and shows the configured confirmation message first.
What the check found
An update can be detected in three independent ways — a newer version string, a newer file version, or a differing checksum — and PendingNewVersion, PendingNewFileVersion, and PendingNewChecksum report which one fired. They are filled in by NewVersionAvailable, so read them only after that call returned True; the two string properties stay empty and PendingNewChecksum stays -1 for a comparison that did not detect anything. That makes them the right values to show the user, and to record in a log, before starting the update.
uses
FMX.TMSFNCAppUpdate;
procedure TForm1.CheckForUpdateButtonClick(Sender: TObject);
begin
AppUpdate1.URL := 'https://downloads.example.com/myapp/update.inf';
if not AppUpdate1.NewVersionAvailable then
begin
ShowMessage('You are running the latest version.');
Exit;
end;
// The three Pending properties report which comparison detected the update
// during the most recent NewVersionAvailable call, so read them only after
// that call returned True. Each stays at its empty value when the update was
// not found through that particular comparison.
if AppUpdate1.PendingNewVersion <> '' then
Memo1.Lines.Add('New application version: ' + AppUpdate1.PendingNewVersion);
if AppUpdate1.PendingNewFileVersion <> '' then
Memo1.Lines.Add('New file version: ' + AppUpdate1.PendingNewFileVersion);
// PendingNewChecksum is -1 when no checksum difference was detected.
if AppUpdate1.PendingNewChecksum <> -1 then
Memo1.Lines.Add('New checksum: ' + IntToStr(AppUpdate1.PendingNewChecksum));
AppUpdate1.StartUpdate;
end;
Elevation for system-level installs
Elevate controls whether the update runs with administrative rights when the files have to be written to a protected location; it defaults to True. On Windows the component spawns an elevated helper process automatically.
Custom version comparison
Handle OnVersionComparison to override the default version-string comparison with your own logic. The handler receives the local version and the remote one and decides, through AIsNewVersion, whether the remote version counts as an update.
uses
FMX.TMSFNCAppUpdate;
procedure TForm1.FormCreate(Sender: TObject);
begin
AppUpdate1.OnVersionComparison := AppUpdate1VersionComparison;
end;
procedure TForm1.AppUpdate1VersionComparison(Sender: TObject;
AOldVersion: string; ANewVersion: string; var AIsNewVersion: Boolean);
begin
// AOldVersion is the locally installed version, ANewVersion the one read
// from the control file. Set AIsNewVersion to decide whether the remote
// version counts as an update.
AIsNewVersion := CompareSemanticVersions(ANewVersion, AOldVersion) > 0;
end;
Logging
Set Logging.Enabled and Logging.Filename to have the component write a detailed update log. Log writes your own message into that same file, so application context — who started the check, what was decided, why a restart was postponed — lands in the same chronological record as the component's own entries. Enable logging first: Log has no file to write to otherwise.
uses
FMX.TMSFNCAppUpdate;
procedure TForm1.FormCreate(Sender: TObject);
begin
// Log appends to the file the component itself writes to, so enable logging
// and point it at a file first - without that there is nothing to write to.
AppUpdate1.Logging.Enabled := True;
AppUpdate1.Logging.Filename := ChangeFileExt(ParamStr(0), '.update.log');
AppUpdate1.OnFileDownloaded := AppUpdate1FileDownloaded;
AppUpdate1.OnAppRestart := AppUpdate1AppRestart;
end;
procedure TForm1.CheckForUpdateButtonClick(Sender: TObject);
begin
AppUpdate1.Log('Update check started');
if AppUpdate1.NewVersionAvailable then
AppUpdate1.Log('Update found: ' + AppUpdate1.PendingNewVersion)
else
AppUpdate1.Log('No update available');
end;
procedure TForm1.AppUpdate1FileDownloaded(Sender: TObject;
FileItem: TTMSFNCAppUpdateFile; StatusCode: Integer);
begin
// Interleaving your own entries with the component's own lines keeps the
// sequence readable when a failed update has to be diagnosed after the fact.
AppUpdate1.Log(Format('Downloaded %s (status %d)', [FileItem.URL, StatusCode]));
end;
procedure TForm1.AppUpdate1AppRestart(Sender: TObject; var Allow: Boolean);
begin
{ FHasUnsavedWork is your own flag for pending user changes. }
Allow := not FHasUnsavedWork;
if not Allow then
AppUpdate1.Log('Restart postponed: unsaved changes');
end;