Files
lazarus-ccr/components/lazautoupdate/latest_stable/trayicon/umainform.pas

767 lines
26 KiB
ObjectPascal
Raw Normal View History

unit umainform;
{ LazAutoUpdater Tray Updater
Copyright (C)2014 Gordon Bamber minesadorada@charcodelvalle.com
An example of using LazAutoUpdate as a silent updater
This source is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This code is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
A copy of the GNU General Public License is available on the World Wide Web
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
SUMMARY
=======
TrayUpdater is a companion to LazAutoUpdate and UpdatePack
It sits in the system tray, and automatically checks for updates
and optionally auto-updates any apps for which it has a profile
It uses an array of custom component LongTimers in order to
update a number of different apps on different schedules
It uses a config file LAUTray.ini to keep track. This file
is automatically generated by UpdatePack and imported by this app when first run.
VERSION HISTORY
===============
0.1.12: Updated to Laz 1.7 fpc 3.1.1
0.1.12: Updated lpr to correctly hide the mainform on startup
0.1.12: Commit to svn
0.1.13: Updated January 2017
Ini filename uses C_PFX
0.1.14: Memory leaks fixed
0.1.15: ??
}
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, LazFileUtils, Forms, Dialogs, ExtCtrls,
Menus, uLongTimer, ulazautoupdate, inifiles, eventlog, strUtils, uconfigform
{$IFDEF WINDOWS}, registry{$ENDIF};
type
{ TAppRec - in-memory storage for all settings }
TAppRec = record
AppPrettyName: string;
AppPath: string;
INIPath: string;
ZipPath: string;
AppVersion: string;
SFProjectName: string;
SFUpdatesDirectory: string;
Location: string;
IntervalType: word;
IntervalDay: word;
IntervalDate: word;
IntervalHour: word;
Update: boolean;
LastCheckDateTime: TDateTime;
end;
{ Tmainform }
Tmainform = class(TForm)
Logger: TEventLog;
idleReminder: TIdleTimer;
LazAutoUpdate1: TLazAutoUpdate;
mnu_About: TMenuItem;
mnu_SelfCheck: TMenuItem;
mnu_startAtOSStartUp: TMenuItem;
mnu_configure: TMenuItem;
mnu_fileExit: TMenuItem;
PopupMenu1: TPopupMenu;
TrayIcon1: TTrayIcon;
procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
procedure FormCreate(Sender: TObject);
procedure FormWindowStateChange(Sender: TObject);
procedure idleReminderTimer(Sender: TObject);
procedure LazAutoUpdate1DebugEvent(Sender: TObject; WhereAt, Message: string);
procedure mnu_AboutClick(Sender: TObject);
procedure mnu_configureClick(Sender: TObject);
procedure mnu_fileExitClick(Sender: TObject);
procedure mnu_startAtOSStartUpClick(Sender: TObject);
procedure mnu_SelfCheckClick(Sender: TObject);
procedure TrayIcon1Click(Sender: TObject);
function UT_DateTimeToStr(TheDate: TDateTime): string;
function UT_StrToDate(str: string): TDateTime;
private
{ private declarations }
szImportINIPath: string;
DebugMode: boolean;
procedure DoAlert(aAppname, aVersion: string);
// Transfers info from lauimport.ini to local ini
function ImportINIFile: boolean;
// When first run, Populates INI and AppRecArray with default entry
procedure PopulateOwnProfile;
// Transfers info from local INI to AppRecArray
procedure DoReadINIIntoAppRecArray;
// Re-initialises a LongTimer array from AppRecArray info
procedure DoSetupLongTimerArray;
// All LongTimers use this for their OnTimer event
procedure DoLongTimerEvent(Sender: TObject);
// Do a silent check/install for this AppRecArray member
procedure CheckAndUpdate(ARecIndex: integer);
public
{ public declarations }
INI: TIniFile;
AppRecArray: array of TAppRec; // Dynamic array
LongTimerArray: array of TLongTimer; // Dynamic array
iCurrentRecIndex: integer;
// Transfers info from AppRecArray to local INI
procedure DoWriteAppRecArrayIntoINI;
end;
var
mainform: Tmainform;
const
{$IFDEF WINDOWS}
C_OS = 'win';
{$ELSE}
C_OS = 'linux';
{$ENDIF}
{$IFDEF CPU32}
C_BITNESS = '32';
{$ELSE}
C_BITNESS = '64';
{$ENDIF}
C_PFX = C_OS + C_BITNESS;
C_LAUTRayINI = 'lauimport.ini';
C_INIFilename = 'trayupdater' + C_PFX + '.ini';
implementation
resourcestring
rs_balloontitle = '%s service';
rs_trayloaded = '%s Loaded';
rs_newversionavailable = 'A new version of %s (v%s) is available';
// TODO: Put all the other strings here
{$R *.lfm}
{ Tmainform }
procedure Tmainform.DoWriteAppRecArrayIntoINI;
// AppRecArray is an in-memory copy of the INI file
var
i: integer;
szSection: string;
begin
if High(AppRecArray) = 0 then
Exit;
for i := Low(AppRecArray) to High(AppRecArray) do
begin
szSection := AppRecArray[i].AppPrettyName;
try
INI.WriteString(szSection, 'AppPrettyName', AppRecArray[i].AppPrettyName);
INI.WriteString(szSection, 'AppPath', AppRecArray[i].AppPath);
INI.WriteString(szSection, 'INIPath', AppRecArray[i].INIPath);
INI.WriteString(szSection, 'ZipPath', AppRecArray[i].ZipPath);
INI.WriteString(szSection, 'AppVersion', AppRecArray[i].AppVersion);
INI.WriteString(szSection, 'SFProjectName', AppRecArray[i].SFProjectName);
INI.WriteString(szSection, 'SFUpdatesDirectory',
AppRecArray[i].SFUpdatesDirectory);
INI.WriteString(szSection, 'Location', AppRecArray[i].Location);
INI.WriteInteger(szSection, 'IntervalType', AppRecArray[i].IntervalType);
INI.WriteInteger(szSection, 'IntervalDate', AppRecArray[i].IntervalDate);
INI.WriteInteger(szSection, 'IntervalDay', AppRecArray[i].IntervalDay);
INI.WriteInteger(szSection, 'IntervalHour', AppRecArray[i].IntervalHour);
INI.WriteInteger(szSection, 'IntervalHour', AppRecArray[i].IntervalHour);
INI.WriteBool(szSection, 'Update', AppRecArray[i].Update);
INI.WriteString(szSection, 'LastCheckDateTime',
UT_DateTimeToStr(AppRecArray[i].LastCheckDateTime));
INI.UpdateFile;
except
if DebugMode then
Logger.Error('Failed to write AppRecArray to %s', [INI.Filename])
end;
end;
end;
procedure Tmainform.DoLongTimerEvent(Sender: TObject);
// All LongTimerArray.OnTimer events go here
// The Tag property is the same as the AppRecArray entry it relates to
var
iTag: integer;
begin
iTag := 0;
// Assertion check
if Sender is TLongTimer then
begin
iTag := TLongTimer(Sender).Tag;
end;
if DebugMode then
Logger.Log('Timer for %s fired', [AppRecArray[iTag].AppPrettyName]);
TrayIcon1.BalloonHint :=
Format('Checking %s for updates', [AppRecArray[iTag].AppPrettyName]);
TrayIcon1.ShowBalloonHint;
CheckAndUpdate(iTag);
// AppRecArray[iTag].LastCheckDateTime := Now();
end;
procedure Tmainform.DoSetupLongTimerArray;
// This is called every time the AppRecArray is changed
// Each profile has a LongTimer associated with it in LongTimerArray()
// If the AppRecArray.Update=TRUE then the associated LongTimer is enabled
// 1. Destroy and clear all the LongTimers aready allocated
// 2. Iterate through the AppRecArray, setting up a new LongTimer for each element
// 3. Enable the LongTimers for which AppArray.Update=TRUE
var
i, iArrayElement: integer;
begin
// Start with an empty array
for i := Low(LongTimerArray) to High(LongTimerArray) do
if LongTimerArray[i] <> nil then
begin
LongTimerArray[i].Enabled := False;
FreeAndNil(LongTimerArray[i]);
end;
SetLength(LongTimerArray, 0); // Zeros the array
iArrayElement := -1;
for i := Low(AppRecArray) to High(AppRecArray) do
begin
Inc(iArrayElement); // initially to zero
SetLength(LongTimerArray, iArrayElement + 1);
LongTimerArray[iArrayElement] := TLongTimer.Create(nil);
with AppRecArray[i] do
begin
case IntervalType of
0: LongTimerArray[iArrayElement].IntervalType := lt1Daily;
1: LongTimerArray[iArrayElement].IntervalType := lt2Weekly;
2: LongTimerArray[iArrayElement].IntervalType := lt3Monthly;
end;
case IntervalDay of
0: LongTimerArray[iArrayElement].WeeklyDay := lt1Monday;
1: LongTimerArray[iArrayElement].WeeklyDay := lt2Tuesday;
2: LongTimerArray[iArrayElement].WeeklyDay := lt3Wednesday;
3: LongTimerArray[iArrayElement].WeeklyDay := lt4Thursday;
4: LongTimerArray[iArrayElement].WeeklyDay := lt5Friday;
5: LongTimerArray[iArrayElement].WeeklyDay := lt6Saturday;
6: LongTimerArray[iArrayElement].WeeklyDay := lt7Sunday;
end;
LongTimerArray[iArrayElement].MonthlyDate := IntervalDate;
LongTimerArray[iArrayElement].Daily24Hour := IntervalHour;
LongTimerArray[iArrayElement].Tag := i;
LongTimerArray[iArrayElement].OnTimer := @DoLongTimerEvent;
// Make sure timer doesn't fire right after a self-update
LongTimerArray[iArrayElement].SampleInterval := lt5Every45Minutes;
LongTimerArray[iArrayElement].Enabled := Update;
end;
end;
end;
function Tmainform.UT_DateTimeToStr(TheDate: TDateTime): string;
var
frmstg: TFormatSettings;
// Ensures consitent String dates across platforms
begin
//GetLocaleFormatSettings(0, frmstg);
frmstg.DateSeparator := '-';
frmstg.ShortDateFormat := 'yyyy-mm-dd';
frmstg.TimeSeparator := '-';
frmstg.LongTimeFormat := 'hh-nn';
Result := DateTimeToStr(TheDate, frmstg);
end;
function Tmainform.UT_StrToDate(str: string): TDateTime;
var
frmstg: TFormatSettings;
// Ensures consitent String dates across platforms
begin
//GetLocaleFormatSettings(0, frmstg);
frmstg.DateSeparator := '-';
frmstg.ShortDateFormat := 'yyyy-mm-dd';
frmstg.TimeSeparator := '-';
frmstg.LongTimeFormat := 'hh-nn';
if not TryStrToDateTime(str, Result, frmstg) then
Result := Now();
end;
procedure Tmainform.DoReadINIIntoAppRecArray;
// AppRecArray is an in-memory copy of the INI file
var
SectionStringList: TStringList;
szSection: string;
i, iArrayElement: integer;
begin
SetLength(AppRecArray, 0); // Zeros the array
SectionStringList := TStringList.Create;
try
try
// Fetch all the section names
INI.ReadSections(SectionStringList);
iArrayElement := -1;
if SectionStringList.Count > 0 then
for i := 0 to SectionStringList.Count - 1 do
begin // Loop through all the INI file sections
szSection := SectionStringList[i];
// Skip over the ProgramInfo section
if (szSection <> 'ProgramInfo') then
begin
Inc(iArrayElement); // initially to zero
SetLength(AppRecArray, iArrayElement + 1);
AppRecArray[iArrayElement].AppPrettyName :=
INI.ReadString(szSection, 'AppPrettyName', '');
AppRecArray[iArrayElement].AppPath :=
INI.ReadString(szSection, 'AppPath', '');
AppRecArray[iArrayElement].INIPath :=
INI.ReadString(szSection, 'INIPath', '');
AppRecArray[iArrayElement].ZipPath :=
INI.ReadString(szSection, 'ZipPath', '');
AppRecArray[iArrayElement].AppVersion :=
INI.ReadString(szSection, 'AppVersion', '');
AppRecArray[iArrayElement].SFProjectName :=
INI.ReadString(szSection, 'SFProjectName', '');
AppRecArray[iArrayElement].SFUpdatesDirectory :=
INI.ReadString(szSection, 'SFUpdatesDirectory', '');
AppRecArray[iArrayElement].Location :=
INI.ReadString(szSection, 'Location', '');
AppRecArray[iArrayElement].IntervalType :=
INI.ReadInteger(szSection, 'IntervalType', 0);
AppRecArray[iArrayElement].IntervalDate :=
INI.ReadInteger(szSection, 'IntervalDate', 1);
AppRecArray[iArrayElement].IntervalDay :=
INI.ReadInteger(szSection, 'IntervalDay', 0);
AppRecArray[iArrayElement].IntervalHour :=
INI.ReadInteger(szSection, 'IntervalHour', 9);
AppRecArray[iArrayElement].Update :=
INI.ReadBool(szSection, 'Update', False);
AppRecArray[iArrayElement].LastCheckDateTime :=
UT_StrToDate(INI.ReadString(szSection, 'LastCheckDateTime',
UT_DateTimeToStr(Now)));
end;
end;
except
if DebugMode then
Logger.Error('Failed to read AppRecArray from %s', [INI.Filename])
end;
finally
FreeAndNil(SectionStringList);
end;
// Low(AppRecArray) to High(AppRecArray) iterates the whole array
end;
procedure Tmainform.PopulateOwnProfile;
// Only called when app is first run
var
szSection, szOSsuffix: string;
begin
szSection := Application.Title;
szOSsuffix := LowerCase(
{$I %FPCTARGETOS%}
);
szSection += szOSsuffix;
with INI do
begin
WriteString(szSection, 'AppPrettyName', szSection);
WriteString(szSection, 'AppPath', ParamStr(0));
WriteString(szSection, 'Location', ProgramDirectory);
WriteString(szSection, 'INIPath', 'lautraynotify' + szOSsuffix + '.ini');
WriteString(szSection, 'ZipPath', 'lautraynotify' + szOSsuffix + '.zip');
WriteString(szSection, 'AppVersion', LazAutoUpdate1.AppVersion);
WriteString(szSection, 'SFProjectName', 'lazautoupdate');
WriteString(szSection, 'SFUpdatesDirectory', 'updates');
WriteInteger(szSection, 'IntervalType', 0); // lt1Daily
WriteInteger(szSection, 'IntervalDay', 0); // lt1Monday (dummy)
WriteInteger(szSection, 'IntervalDate', 1); // 1st Month (dummy)
WriteInteger(szSection, 'IntervalHour', 9); // 9am
WriteBool(szSection, 'Update', False); // Dont autoupdate the default profile!
WriteString(szSection, 'LastCheckDateTime', UT_DateTimeToStr(Now));
WriteBool('ProgramInfo', 'IsVirgin', False);
UpdateFile;
end;
with LazAutoUpdate1 do
begin
VersionsININame := 'lautraynotify' + szOSsuffix + '.ini';
ZipFileName := 'lautraynotify' + szOSsuffix + '.zip';
UpdatesFolder := 'updates';
SFProjectName := 'lazautoupdate';
end;
DoReadINIIntoAppRecArray;
if not FileExistsUTF8(C_LAUTRayINI) then
LazAutoUpdate1.CreateLocalLauImportFile;
LazAutoUpdate1.RelocateLauImportFile;
end;
function Tmainform.ImportINIFile: boolean;
// Copies ini info from shared AppData directory
// Appends Location info to the AppPath entry
// Sets Update=TRUE
// into C_INIFilename then deletes source ini
var
ImportINI: TIniFile;
SectionStringList, SectionContents: TStringList;
i: integer;
szSection, szKey, szLocation, szAppPath: string;
begin
{TODO: Preserve user Logtimer settings?}
Result := False;
if not FileExists(szImportINIPath) then
Exit;
ImportINI := TIniFile.Create(szImportINIPath);
SectionStringList := TStringList.Create;
SectionContents := TStringList.Create;
try
ImportINI.ReadSections(SectionStringList);
if SectionStringList.Count > 0 then
begin
szSection := SectionStringList[0];
ImportINI.ReadSection(szSection, SectionContents);
for i := 0 to SectionContents.Count - 1 do
begin
szKey := SectionContents[i];
if szKey = 'Location' then
szLocation := ImportINI.ReadString(szSection, szKey, '');
if szKey = 'AppPath' then
szAppPath := ImportINI.ReadString(szSection, szKey, '');
INI.WriteString(szSection, szKey, ImportINI.ReadString(
szSection, szKey, ''));
end;
// Append Location to AppPath
if ((szAppPath <> '') and (szLocation <> '')) then
INI.WriteString(szSection, 'AppPath', AppendPathDelim(szLocation) +
ExtractFilename(szAppPath));
INI.WriteBool(szSection, 'Update', True);
INI.WriteString(szSection, 'LastCheckDateTime',
UT_DateTimeToStr(Now));
INI.UpdateFile;
Result := True;
end;
finally
FreeAndNil(SectionContents);
FreeAndNil(SectionStringList);
FreeAndNil(ImportINI);
end;
if (Result = True) then
begin
if DebugMode then
Logger.Log('%s: Imported %s into %s',
[Application.Title, szImportINIPath, INI.Filename]);
DoReadINIIntoAppRecArray;
end;
end;
procedure Tmainform.DoAlert(aAppname, aVersion: string);
begin
TrayIcon1.BalloonHint := Format(rs_newversionavailable, [aAppname, aVersion]);
TrayIcon1.ShowBalloonHint;
end;
procedure Tmainform.FormWindowStateChange(Sender: TObject);
begin
if mainform.WindowState = wsMinimized then
begin
// 2 lines below are ineffective at hiding the main form
// Replaced with Application.ShowMainForm := false; in the lpr
// mainform.WindowState := wsNormal;
// mainform.Hide;
mainform.ShowInTaskBar := stNever;
// Log a successful startup
if DebugMode then
Logger.Active := True;
if DebugMode then
Logger.Log('%s version %s started OK',
[Application.Title, LazAutoUpdate1.AppVersion]);
end;
end;
procedure Tmainform.idleReminderTimer(Sender: TObject);
// IdleTimer checks for any new C_LAUTRayINI in the AppData folder
// If found, it is imported then deleted.
begin
if LazAutoUpdate1.DownloadInprogress then
begin
TrayIcon1.BalloonHint := 'Download in progress';
TrayIcon1.ShowBalloonHint;
Exit;
end;
if FileExists(szImportINIPath) then
begin
if DebugMode then
Logger.Log('%s: Import file %s discovered',
[Application.Title, szImportINIPath]);
if ImportINIFile then
begin
if DebugMode then
Logger.Log('%s: Import file %s successfully imported',
[Application.Title, szImportINIPath]);
DeleteFileUTF8(szImportINIPath);
end
else
if DebugMode then
Logger.Error('%s: Failed to import file %s',
[Application.Title, szImportINIPath]);
end;
end;
procedure Tmainform.LazAutoUpdate1DebugEvent(Sender: TObject; WhereAt, Message: string);
begin
if ((Logger.Active) and (DebugMode = True)) then
Logger.Log('LazAutoUpdate:%s Message:%s', [WhereAt, Message]);
end;
procedure Tmainform.mnu_AboutClick(Sender: TObject);
var
sz: string;
begin
LazAutoUpdate1.ResetAppVersion;
sz := Application.Title + ' system tray application' + LineEnding;
sz += Format('Version %s', [LazAutoUpdate1.AppVersion]) + LineEnding;
sz += 'License: LGPLv2' + LineEnding + LineEnding;
sz += Format('Using LazAutoUpdate v%s', [LazAutoUpdate1.AutoUpdateVersion]) +
LineEnding;
sz += Format('%s %s', [LazAutoUpdate1.LCLVersion, LazAutoUpdate1.FPCVersion]) +
LineEnding;
sz += Format('Compiled %s', [LazAutoUpdate1.LastCompiled]) + LineEnding;
MessageDlg('About ' + Application.Title,
sz, mtInformation, [mbOK], 0);
end;
procedure Tmainform.mnu_configureClick(Sender: TObject);
begin
DoReadINIIntoAppRecArray;
LazAutoUpdate1.ShowWhatsNewIfAvailable;
configform.ShowModal;
// may alter AppRecArray
DoSetupLongTimerArray;
DoWriteAppRecArrayIntoINI;
end;
procedure Tmainform.mnu_fileExitClick(Sender: TObject);
begin
DoWriteAppRecArrayIntoINI;
Close;
end;
procedure Tmainform.mnu_startAtOSStartUpClick(Sender: TObject);
{$IFDEF WINDOWS}
var
Reg: TRegistry;
{$ENDIF}
begin
{$IFDEF WINDOWS}
Reg := TRegistry.Create(KEY_ALL_ACCESS);
try
Reg.RootKey := HKEY_CURRENT_USER;
Reg.OpenKey('\Software\Microsoft\Windows\CurrentVersion\Run', False);
if mnu_startAtOSStartUp.Checked then
begin
Reg.WriteString(Application.Title, ParamStr(0));
INI.WriteBool('ProgramInfo', 'RunAtStartUp', True);
if DebugMode then
Logger.Log('Run at OS startup Activated');
MessageDlg(Application.Title,
'Run at OS startup activated OK', mtInformation, [mbOK], 0);
end
else
begin
Reg.DeleteValue(Application.Title);
INI.WriteBool('ProgramInfo', 'RunAtStartUp', False);
if DebugMode then
Logger.Log('Run at OS startup Deactivated');
MessageDlg(Application.Title,
'Run at OS startup deactivated OK', mtInformation, [mbOK], 0);
end;
Reg.CloseKey;
finally
FreeAndNil(Reg);
end;
{$ELSE}
if mnu_startAtOSStartUp.Checked then
begin
ShowMessage('Sorry - not implemented in Linux in this version');
mnu_startAtOSStartUp.Checked := False;
end;
{$ENDIF}
end;
procedure TmainForm.CheckAndUpdate(ARecIndex: integer);
begin
if LazAutoUpdate1.DownloadInprogress then
begin
if DebugMode then
Logger.Error(
'Tried to update whilst download in progress. Exiting CheckAndUpdate routine');
Exit;
end;
with AppRecArray[ARecIndex] do
begin
LazAutoUpdate1.AppFileWithPath := AppPath;
LazAutoUpdate1.AppVersion := AppVersion;
LazAutoUpdate1.ZipfileName := ZipPath;
LazAutoUpdate1.SFProjectName := SFProjectName;
LazAutoUpdate1.UpdatesFolder := SFUpdatesDirectory;
LazAutoUpdate1.VersionsININame := INIPath;
LazAutoUpdate1.CopyTree := True;
TrayIcon1.BalloonHint :=
Format('Checking %s for updates', [AppPrettyName]);
TrayIcon1.ShowBalloonHint;
// Debugging line
LazAutoUpdate1.DebugMode := True; // Logs everyting
if LazAutoUpdate1.NewVersionAvailable then
begin
TrayIcon1.BalloonHint :=
Format('Found newer version %s. Downloading...',
[LazAutoUpdate1.GUIOnlineVersion]);
TrayIcon1.ShowBalloonHint;
if LazAutoUpdate1.DownloadNewVersion then
if LazAutoUpdate1.SilentUpdate then
begin
TrayIcon1.BalloonHint :=
Format('Successfully updated %s to version %s',
[AppPrettyName, LazAutoUpdate1.GUIOnlineVersion]);
LastCheckDateTime := Now;
end
else
TrayIcon1.BalloonHint := Format('Failed to update %s', [AppPrettyName]);
end
else
begin
TrayIcon1.BalloonHint := AppPrettyName + ' is up-to-date';
TrayIcon1.ShowBalloonHint;
end;
LazAutoUpdate1.ResetAppVersion;
TrayIcon1.ShowBalloonHint;
end;
end;
procedure Tmainform.mnu_SelfCheckClick(Sender: TObject);
// iCurrentRecIndex is the selected profile
begin
// Production line
//CheckAndUpdate(0); // Default profile (self)
//Debugging line
if DebugMode then
Logger.Active := True;
ShowMessageFmt('Update %s', [AppRecArray[iCurrentRecIndex].AppPrettyName]);
CheckAndUpdate(iCurrentRecIndex);
end;
procedure Tmainform.TrayIcon1Click(Sender: TObject);
begin
if LazAutoUpdate1.DownloadInprogress then
begin
TrayIcon1.BalloonHint := 'Currently downloading...';
TrayIcon1.ShowBalloonHint;
end;
end;
procedure Tmainform.FormCreate(Sender: TObject);
begin
if LowerCase(ParamStr(1)) = 'debug' then
DebugMode := True
else
DebugMode := False;
{$IFDEF DEBUGMODE}
DebugMode := True;
{$ENDIF}
// Initialise the App's main INI file
try
INI := TIniFile.Create(GetAppConfigDirUTF8(False) + C_INIFilename);
except
sleep(4000);
if (INI = nil) then
INI := TIniFile.Create(GetAppConfigDirUTF8(False) + C_INIFilename);
end;
INI.CacheUpdates := False;
INI.WriteString('ProgramInfo', 'AppName', Application.Title);
INI.WriteString('ProgramInfo', 'Location', LazAutoUpdate1.AppFileWithPath);
INI.WriteString('ProgramInfo', 'Version', LazAutoUpdate1.AppVersion);
INI.WriteString('ProgramInfo', 'LastStarted',
FormatDateTime(shortdateformat, Now));
mnu_startAtOSStartUp.Checked := INI.ReadBool('ProgramInfo', 'RunAtStartUp', False);
// Is this a first-time run?
if INI.ReadBool('ProgramInfo', 'IsVirgin', True) then
PopulateOwnProfile;
// Start up a system Event Log
if DebugMode then
Logger.LogType := ltFile;
if DebugMode then
Logger.Filename := ExtractFileNameWithoutExt(ParamStr(0)) + '.log';
// New logfile every time
if DebugMode then
if FileExistsUTF8(Logger.Filename) then
DeleteFile(Logger.Filename);
if DebugMode then
Logger.AppendContent := True;
if DebugMode then
Logger.DefaultEventType := etInfo;
if DebugMode then
Logger.RaiseExceptionOnError := False;
// Logger.Identification := Application.Title;
// Fetch the location of any trayicon INI on the users system
szImportINIPath := GetAppConfigDirUTF8(False, True);
szImportINIPath := AnsiReplaceText(szImportINIPath, Application.Title,
'updatehm' + C_PFX);
szImportINIPath := AppendPathDelim(szImportINIPath) + C_LAUTRayINI;
if DebugMode then
Logger.Debug('szImportINIPath=' + szImportINIPath);
// Initialise the AppRecArray
DoReadINIIntoAppRecArray;
// Use last saved Profile at startup
iCurrentRecIndex := mainform.INI.ReadInteger('ProgramInfo',
'CurrentProfileIndex', 0);
DoSetupLongTimerArray;
// Sort out the TrayIcon stuff
TrayIcon1.Icon := Application.Icon;
TrayIcon1.BalloonTitle := Format(rs_balloontitle, [Application.Title]);
TrayIcon1.Hint := Application.Title;
TrayIcon1.ShowIcon := True;
TrayIcon1.Show;
TrayIcon1.BalloonHint := Format(rs_trayloaded, [Application.Title]);
TrayIcon1.ShowBalloonHint;
LazAutoUpdate1.DebugMode := DebugMode;
mnu_SelfCheck.Visible := DebugMode;
end;
procedure Tmainform.FormCloseQuery(Sender: TObject; var CanClose: boolean);
var
i: integer;
begin
if LazAutoUpdate1.DownloadInprogress then
begin
ShowMessage('Please wait. Update in progress');
CanClose := False;
end
else
// Clean up memory No leaks (V0.1.14)
begin
if DebugMode then
begin
Logger.Log('User closed application');
Logger.Active := False;
FreeAndNil(Logger);
end;
CanClose := True;
end;
if CanClose then
begin
// Clean up any LongTimers
for i := Low(LongTimerArray) to High(LongTimerArray) do
if LongTimerArray[i] <> nil then
begin
LongTimerArray[i].Enabled := False;
FreeAndNil(LongTimerArray[i]);
end;
SetLength(AppRecArray, 0);
FreeAndNil(AppRecArray);
FreeAndNil(INI);
end;
end;
end.