You've already forked lazarus-ccr
To V0.2.0.0: Work-in-progress.
Main functions working OK git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5638 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -52,8 +52,8 @@ A component for SourceForge Project Developers and end-users to update their app
|
|||||||
along with this library; if not, write to the Free Software Foundation,
|
along with this library; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
"/>
|
"/>
|
||||||
<Version Minor="1" Release="28"/>
|
<Version Minor="2"/>
|
||||||
<Files Count="4">
|
<Files Count="5">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="ulazautoupdate.pas"/>
|
<Filename Value="ulazautoupdate.pas"/>
|
||||||
<HasRegisterProc Value="True"/>
|
<HasRegisterProc Value="True"/>
|
||||||
@ -72,19 +72,20 @@ A component for SourceForge Project Developers and end-users to update their app
|
|||||||
<Filename Value="uappisrunning.pas"/>
|
<Filename Value="uappisrunning.pas"/>
|
||||||
<UnitName Value="uappisrunning"/>
|
<UnitName Value="uappisrunning"/>
|
||||||
</Item4>
|
</Item4>
|
||||||
|
<Item5>
|
||||||
|
<Filename Value="lazautoupdate_httpclient.pas"/>
|
||||||
|
<UnitName Value="lazautoupdate_httpclient"/>
|
||||||
|
</Item5>
|
||||||
</Files>
|
</Files>
|
||||||
<i18n>
|
<i18n>
|
||||||
<EnableI18N Value="True"/>
|
<EnableI18N Value="True"/>
|
||||||
<OutDir Value="locale"/>
|
<OutDir Value="locale"/>
|
||||||
<EnableI18NForLFM Value="True"/>
|
<EnableI18NForLFM Value="True"/>
|
||||||
</i18n>
|
</i18n>
|
||||||
<RequiredPkgs Count="2">
|
<RequiredPkgs Count="1">
|
||||||
<Item1>
|
<Item1>
|
||||||
<PackageName Value="laz_synapse40_1"/>
|
|
||||||
</Item1>
|
|
||||||
<Item2>
|
|
||||||
<PackageName Value="IDEIntf"/>
|
<PackageName Value="IDEIntf"/>
|
||||||
</Item2>
|
</Item1>
|
||||||
</RequiredPkgs>
|
</RequiredPkgs>
|
||||||
<UsageOptions>
|
<UsageOptions>
|
||||||
<CustomOptions Value="-dUseCThreads"/>
|
<CustomOptions Value="-dUseCThreads"/>
|
||||||
|
@ -4,11 +4,12 @@
|
|||||||
|
|
||||||
unit lazupdate;
|
unit lazupdate;
|
||||||
|
|
||||||
|
{$warn 5023 off : no warning about unused units}
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
ulazautoupdate, aboutlazautoupdateunit, VersionSupport, uappisrunning,
|
ulazautoupdate, aboutlazautoupdateunit, VersionSupport, uappisrunning,
|
||||||
LazarusPackageIntf;
|
lazautoupdate_httpclient, LazarusPackageIntf;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
unit ulazautoupdate;
|
unit ulazautoupdate;
|
||||||
|
|
||||||
{
|
{
|
||||||
Original DownloadHTTP code: wiki.freepascal.org
|
|
||||||
Thread source: http://freepascalanswers.wordpress.com/2012/06/15/synapas-http-thread/
|
|
||||||
VersionSupport: Mike Thompson - mike.cornflake@gmail.com
|
VersionSupport: Mike Thompson - mike.cornflake@gmail.com
|
||||||
Added to and modified by minesadorada@charcodelvalle.com
|
Added to and modified by minesadorada@charcodelvalle.com
|
||||||
|
|
||||||
@ -37,21 +35,18 @@ interface
|
|||||||
|
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Forms, Classes, SysUtils, strutils, LazUTF8,FileUtil,LazFileUtils, Dialogs, StdCtrls,
|
Forms, Classes, SysUtils, lazautoupdate_httpclient, strutils,
|
||||||
Buttons, httpsend, DateUtils, asyncprocess, zipper, LResources,
|
LazUTF8, FileUtil, LazFileUtils, Dialogs, StdCtrls,
|
||||||
|
Buttons, DateUtils, asyncprocess, zipper, LResources,
|
||||||
VersionSupport, inifiles, aboutlazautoupdateunit, uappisrunning, LCLProc,
|
VersionSupport, inifiles, aboutlazautoupdateunit, uappisrunning, LCLProc,
|
||||||
fileinfo , winpeimagereader {need this for reading exe info}
|
fileinfo, winpeimagereader {need this for reading exe info}
|
||||||
, elfreader {needed for reading ELF executables}
|
, elfreader {needed for reading ELF executables}
|
||||||
, machoreader {needed for reading MACH-O executables}
|
, machoreader {needed for reading MACH-O executables}
|
||||||
;
|
{$IFDEF WINDOWS},Windows,ShellAPI{$ENDIF}; // Thanks to Windows 10 and 704 error
|
||||||
|
|
||||||
const
|
const
|
||||||
// C_OnlineAppPath =
|
|
||||||
//'https://sourceforge.net/project/%s/files/%s/%s/download';
|
|
||||||
// https://sourceforge.net/projects/lazautoupdate/files/updates/updatepackwin32.zip/download
|
|
||||||
// https://heanet.dl.sourceforge.net/project/lazautoupdate/updates/dboxmonitorwin64.zip
|
|
||||||
C_OnlineAppPath =
|
C_OnlineAppPath =
|
||||||
'http://sourceforge.net/projects/%s/files/%s/%s/download';
|
'https://sourceforge.net/projects/%s/files/%s/%s/download';
|
||||||
// [updatepath,projectname,filename]
|
// [updatepath,projectname,filename]
|
||||||
C_TLazAutoUpdateComponentVersion = '0.2.0';
|
C_TLazAutoUpdateComponentVersion = '0.2.0';
|
||||||
C_LAUTRayINI = 'lauimport.ini';
|
C_LAUTRayINI = 'lauimport.ini';
|
||||||
@ -104,13 +99,13 @@ const
|
|||||||
More checks on PrettyName
|
More checks on PrettyName
|
||||||
V0.1.25:Changed default: CopyTree = TRUE
|
V0.1.25:Changed default: CopyTree = TRUE
|
||||||
V0.1.26:Updated uses clause for FileUtils.
|
V0.1.26:Updated uses clause for FileUtils.
|
||||||
V0.2.0: ??
|
V0.2.0: Rewritten for 2017
|
||||||
}
|
}
|
||||||
C_TThreadedDownloadComponentVersion = '0.0.2';
|
C_TThreadedDownloadComponentVersion = '0.0.3';
|
||||||
{
|
{
|
||||||
V0.0.1: Initial alpha
|
V0.0.1: Initial alpha
|
||||||
V0.0.2: Added fDebugmode to all classes and functions
|
V0.0.2: Added fDebugmode to all classes and functions
|
||||||
V0.0.3: ??
|
V0.0.3: Changed to http_client
|
||||||
}
|
}
|
||||||
C_OnlineVersionsININame = 'versions.ini'; // User can change
|
C_OnlineVersionsININame = 'versions.ini'; // User can change
|
||||||
C_UpdatesFolder = 'updates'; // User can change
|
C_UpdatesFolder = 'updates'; // User can change
|
||||||
@ -119,10 +114,13 @@ const
|
|||||||
C_GUIEntry = 'GUI';
|
C_GUIEntry = 'GUI';
|
||||||
C_ModuleEntry = 'Module';
|
C_ModuleEntry = 'Module';
|
||||||
{$IFDEF WINDOWS}
|
{$IFDEF WINDOWS}
|
||||||
C_Updater = 'updatehm.exe';
|
{$IFDEF CPU32}C_Updater = 'updatehmwin32.exe';{$ENDIF}
|
||||||
|
{$IFDEF CPU64}C_Updater = 'updatehmwin64.exe';{$ENDIF}
|
||||||
C_LOCALUPDATER = 'lauupdate.exe';
|
C_LOCALUPDATER = 'lauupdate.exe';
|
||||||
{$ELSE}
|
{$ENDIF}
|
||||||
C_Updater = 'updatehm';
|
{$IFDEF LINUX}
|
||||||
|
{$IFDEF CPU32}C_Updater = 'updatehmlinux32';{$ENDIF}
|
||||||
|
{$IFDEF CPU64}C_Updater = 'updatehmlinux64';{$ENDIF}
|
||||||
C_LOCALUPDATER = 'lauupdate';
|
C_LOCALUPDATER = 'lauupdate';
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
@ -188,14 +186,15 @@ type
|
|||||||
OnlineVersion: string) of object;
|
OnlineVersion: string) of object;
|
||||||
TOnDownloaded = procedure(Sender: TObject; ResultCode, BytesDownloaded: integer) of
|
TOnDownloaded = procedure(Sender: TObject; ResultCode, BytesDownloaded: integer) of
|
||||||
object;
|
object;
|
||||||
TOnDebugEvent = procedure(Sender: TObject; lauMethodName, lauMessage: string) of object;
|
TOnDebugEvent = procedure(Sender: TObject; lauMethodName, lauMessage: string) of
|
||||||
|
object;
|
||||||
|
|
||||||
TLazAutoUpdate = class(TAboutLazAutoUpdate)
|
TLazAutoUpdate = class(TAboutLazAutoUpdate)
|
||||||
private
|
private
|
||||||
fSourceForgeProjectName: string;
|
fSourceForgeProjectName: string;
|
||||||
fApplicationVersionString: string;
|
fApplicationVersionString: string;
|
||||||
fApplicationVersionQuad: TVersionQuad;
|
fApplicationVersionQuad: TVersionQuad;
|
||||||
fGuiQuad:TVersionQuad;
|
fGuiQuad: TVersionQuad;
|
||||||
fProjectType: TProjectType;
|
fProjectType: TProjectType;
|
||||||
fThreadDownload: TThreadedDownload;
|
fThreadDownload: TThreadedDownload;
|
||||||
fAppFileName: string;
|
fAppFileName: string;
|
||||||
@ -228,7 +227,7 @@ type
|
|||||||
fSilentMode: boolean;
|
fSilentMode: boolean;
|
||||||
fLCLVersion, fWidgetSet, fFPCVersion, fLastCompiled, fTargetOS: string;
|
fLCLVersion, fWidgetSet, fFPCVersion, fLastCompiled, fTargetOS: string;
|
||||||
fQuad: TVersionQuad;
|
fQuad: TVersionQuad;
|
||||||
fProgVersion:TProgramVersion;
|
fProgVersion: TProgramVersion;
|
||||||
objFileVerInfo: TFileVersionInfo;
|
objFileVerInfo: TFileVersionInfo;
|
||||||
procedure SetProjectType(AValue: TProjectType);
|
procedure SetProjectType(AValue: TProjectType);
|
||||||
// projectype=auOther property Sets
|
// projectype=auOther property Sets
|
||||||
@ -248,7 +247,8 @@ type
|
|||||||
|
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
Procedure DebugTest;
|
destructor Destroy; override;
|
||||||
|
procedure DebugTest;
|
||||||
{Main functions}
|
{Main functions}
|
||||||
// If NewVersionAvailable then DownloadNewVersion then UpdateToNewVersion
|
// If NewVersionAvailable then DownloadNewVersion then UpdateToNewVersion
|
||||||
// Returns TRUE if GUIVersion > AppVersion
|
// Returns TRUE if GUIVersion > AppVersion
|
||||||
@ -301,7 +301,7 @@ type
|
|||||||
property LastError: string read fLastError;
|
property LastError: string read fLastError;
|
||||||
// Debugging use only
|
// Debugging use only
|
||||||
property DebugMode: boolean read fDebugMode write SetDebugMode;
|
property DebugMode: boolean read fDebugMode write SetDebugMode;
|
||||||
// property AppVersionNumber: integer read fApplicationVersionQuad;
|
// property AppVersionNumber: integer read fApplicationVersionQuad;
|
||||||
|
|
||||||
// Info useful for About dialogs
|
// Info useful for About dialogs
|
||||||
property LCLVersion: string read fLCLVersion;
|
property LCLVersion: string read fLCLVersion;
|
||||||
@ -317,7 +317,8 @@ type
|
|||||||
property OnDebugEvent: TOnDebugEvent read fOnDebugEvent write fOnDebugEvent;
|
property OnDebugEvent: TOnDebugEvent read fOnDebugEvent write fOnDebugEvent;
|
||||||
|
|
||||||
// Embedded class
|
// Embedded class
|
||||||
property ThreadDownload: TThreadedDownload read fThreadDownload write fThreadDownload;
|
property ThreadDownload: TThreadedDownload
|
||||||
|
read fThreadDownload write fThreadDownload;
|
||||||
// Set this property before using methods
|
// Set this property before using methods
|
||||||
property SFProjectName: string read fSourceForgeProjectName
|
property SFProjectName: string read fSourceForgeProjectName
|
||||||
write SetSourceForgeProjectName;
|
write SetSourceForgeProjectName;
|
||||||
@ -334,7 +335,7 @@ type
|
|||||||
// Version of this component
|
// Version of this component
|
||||||
property AutoUpdateVersion: string read fComponentVersion;
|
property AutoUpdateVersion: string read fComponentVersion;
|
||||||
// Zipfile contains a whole directory tree (relative to App Directory)
|
// Zipfile contains a whole directory tree (relative to App Directory)
|
||||||
property CopyTree: boolean read fCopyTree write fCopyTree default TRUE;
|
property CopyTree: boolean read fCopyTree write fCopyTree default True;
|
||||||
// Default is 'updates' *must be the same in SourceForge file section*
|
// Default is 'updates' *must be the same in SourceForge file section*
|
||||||
property UpdatesFolder: string read fUpdatesFolder write fUpdatesFolder;
|
property UpdatesFolder: string read fUpdatesFolder write fUpdatesFolder;
|
||||||
// Default=versions.ini File in SourceForge /updates folder
|
// Default=versions.ini File in SourceForge /updates folder
|
||||||
@ -345,7 +346,8 @@ type
|
|||||||
// Set to FALSE if you want to handle them in form code
|
// Set to FALSE if you want to handle them in form code
|
||||||
property ShowDialogs: boolean read fShowDialogs write SetShowDialogs default False;
|
property ShowDialogs: boolean read fShowDialogs write SetShowDialogs default False;
|
||||||
// How many counts to wait until 'Too long' meesage quits out
|
// How many counts to wait until 'Too long' meesage quits out
|
||||||
property VersionCountLimit: cardinal read fVersionCountLimit write fVersionCountLimit;
|
property VersionCountLimit: cardinal read fVersionCountLimit
|
||||||
|
write fVersionCountLimit;
|
||||||
// How many counts to wait until 'Too long' meesage quits out
|
// How many counts to wait until 'Too long' meesage quits out
|
||||||
property DownloadCountLimit: cardinal read fDownloadCountLimit
|
property DownloadCountLimit: cardinal read fDownloadCountLimit
|
||||||
write fDownloadCountLimit;
|
write fDownloadCountLimit;
|
||||||
@ -416,8 +418,9 @@ type
|
|||||||
|
|
||||||
|
|
||||||
// Non-threaded version (redundant v0.0.1)
|
// Non-threaded version (redundant v0.0.1)
|
||||||
function DownloadHTTP(URL, TargetFile: string;
|
|
||||||
var ReturnCode, DownloadSize: integer; bIsSourceForge, fDebugMode: boolean): boolean;
|
function DownloadHTTP(URL, TargetFile: string; var ReturnCode, DownloadSize: integer;
|
||||||
|
bIsSourceForge, fDebugMode: boolean): boolean;
|
||||||
|
|
||||||
procedure Register;
|
procedure Register;
|
||||||
|
|
||||||
@ -443,7 +446,7 @@ begin
|
|||||||
while MilliSecondOfTheDay(Now) < (ThisSecond + MillisecondDelay) do ;
|
while MilliSecondOfTheDay(Now) < (ThisSecond + MillisecondDelay) do ;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Procedure TLazAutoUpdate.DebugTest;
|
procedure TLazAutoUpdate.DebugTest;
|
||||||
begin
|
begin
|
||||||
ShowMessage(fApplicationVersionString);
|
ShowMessage(fApplicationVersionString);
|
||||||
end;
|
end;
|
||||||
@ -470,20 +473,21 @@ begin
|
|||||||
// Grab the application and form objects from the application
|
// Grab the application and form objects from the application
|
||||||
fParentApplication := Tapplication(AOwner.Owner);
|
fParentApplication := Tapplication(AOwner.Owner);
|
||||||
fParentForm := TForm(AOwner);
|
fParentForm := TForm(AOwner);
|
||||||
fApplicationVersionString:='No build information available';
|
fApplicationVersionString := 'No build information available';
|
||||||
objFileVerInfo:=TFileVersionInfo.Create(fParentApplication);
|
objFileVerInfo := TFileVersionInfo.Create(fParentApplication);
|
||||||
TRY
|
try
|
||||||
Try
|
try
|
||||||
objFileVerInfo.Filename:=ParamStrUTF8(0);
|
objFileVerInfo.Filename := ParamStrUTF8(0);
|
||||||
objFileVerInfo.ReadFileInfo;
|
objFileVerInfo.ReadFileInfo;
|
||||||
fApplicationVersionString:=objFileVerInfo.VersionStrings.Values['FileVersion'];
|
fApplicationVersionString := objFileVerInfo.VersionStrings.Values['FileVersion'];
|
||||||
fileinfo.GetProgramVersion(fApplicationVersionQuad);
|
fileinfo.GetProgramVersion(fApplicationVersionQuad);
|
||||||
fileinfo.GetProgramVersion(fProgVersion);
|
fileinfo.GetProgramVersion(fProgVersion);
|
||||||
Except
|
except
|
||||||
// Eat other Exceptions?
|
// Eat other Exceptions?
|
||||||
On E:EResNotFound do
|
On E: EResNotFound do
|
||||||
ShowMessage('There is no version information in your project!');
|
ShowMessage('There is no version information in your project!');
|
||||||
On E:Exception do Application.Terminate;
|
On E: Exception do
|
||||||
|
Application.Terminate;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
objFileVerInfo.Free;
|
objFileVerInfo.Free;
|
||||||
@ -492,7 +496,7 @@ begin
|
|||||||
if (fApplicationVersionString = 'No build information available') then
|
if (fApplicationVersionString = 'No build information available') then
|
||||||
fApplicationVersionString := '0.0.0.0';
|
fApplicationVersionString := '0.0.0.0';
|
||||||
|
|
||||||
fCopyTree := TRUE; // User can change
|
fCopyTree := True; // User can change
|
||||||
// UpdateList: Redundant?
|
// UpdateList: Redundant?
|
||||||
AddToUpdateList('', LazUTF8.ParamStrUTF8(0), GetFileVersion, 0);
|
AddToUpdateList('', LazUTF8.ParamStrUTF8(0), GetFileVersion, 0);
|
||||||
|
|
||||||
@ -553,10 +557,14 @@ begin
|
|||||||
AboutBoxVersion := C_TLazAutoUpdateComponentVersion;
|
AboutBoxVersion := C_TLazAutoUpdateComponentVersion;
|
||||||
AboutBoxAuthorname := 'Gordon Bamber';
|
AboutBoxAuthorname := 'Gordon Bamber';
|
||||||
//AboutBoxOrganisation (string)
|
//AboutBoxOrganisation (string)
|
||||||
AboutBoxAuthorEmail := 'minesadorada@gmail.com';
|
AboutBoxAuthorEmail := 'minesadorada@charcodelvalle.com';
|
||||||
AboutBoxLicenseType := 'MODIFIEDGPL';
|
AboutBoxLicenseType := 'MODIFIEDGPL';
|
||||||
end;
|
end;
|
||||||
|
destructor TLazAutoUpdate.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(fThreadDownload);
|
||||||
|
inherited destroy;
|
||||||
|
end;
|
||||||
function TLazAutoUpdate.AppIsActive(const ExeName: string): boolean;
|
function TLazAutoUpdate.AppIsActive(const ExeName: string): boolean;
|
||||||
begin
|
begin
|
||||||
Result := AppIsRunning(ExeName);
|
Result := AppIsRunning(ExeName);
|
||||||
@ -820,7 +828,8 @@ begin
|
|||||||
VersionINI := TIniFile.Create(sznewINIPath);
|
VersionINI := TIniFile.Create(sznewINIPath);
|
||||||
try
|
try
|
||||||
fGUIOnlineVersion := VersionINI.ReadString(C_INISection, C_GUIEntry, '0.0.0.0');
|
fGUIOnlineVersion := VersionINI.ReadString(C_INISection, C_GUIEntry, '0.0.0.0');
|
||||||
if NOT TryStrToVersionQuad(fGUIOnlineVersion,fGuiQuad) then fGUIQuad:=StrToVersionQuad('0.0.0.0');
|
if not TryStrToVersionQuad(fGUIOnlineVersion, fGuiQuad) then
|
||||||
|
fGUIQuad := StrToVersionQuad('0.0.0.0');
|
||||||
finally
|
finally
|
||||||
VersionINI.Free;
|
VersionINI.Free;
|
||||||
end;
|
end;
|
||||||
@ -840,9 +849,10 @@ begin
|
|||||||
[iGUIVersion, fApplicationVersionQuad]));
|
[iGUIVersion, fApplicationVersionQuad]));
|
||||||
}
|
}
|
||||||
// Test: Is the online version newer?
|
// Test: Is the online version newer?
|
||||||
if NewerVersion(fGUIQuad,fApplicationVersionQuad) then Result:=TRUE;
|
if NewerVersion(fGUIQuad, fApplicationVersionQuad) then
|
||||||
// if (iGUIVersion > fApplicationVersionQuad) then
|
Result := True;
|
||||||
// Result := True;
|
// if (iGUIVersion > fApplicationVersionQuad) then
|
||||||
|
// Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1213,7 +1223,7 @@ function TLazAutoUpdate.CreateLocalLauImportFile: boolean;
|
|||||||
var
|
var
|
||||||
LAUTRayINI: TIniFile;
|
LAUTRayINI: TIniFile;
|
||||||
szSection: string;
|
szSection: string;
|
||||||
szSuffix:String;
|
szSuffix: string;
|
||||||
begin
|
begin
|
||||||
// read the VMT once
|
// read the VMT once
|
||||||
if Assigned(fOndebugEvent) then
|
if Assigned(fOndebugEvent) then
|
||||||
@ -1227,14 +1237,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
// Make up OS-Bitness suffix
|
// Make up OS-Bitness suffix
|
||||||
{$IFDEF WINDOWS}
|
{$IFDEF WINDOWS}
|
||||||
szSuffix:='win';
|
szSuffix := 'win';
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
szSuffix:='linux';
|
szSuffix := 'linux';
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
{$IFDEF CPU64}
|
{$IFDEF CPU64}
|
||||||
szSuffix+='64';
|
szSuffix += '64';
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
szSuffix+='32';
|
szSuffix += '32';
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Result := False;
|
Result := False;
|
||||||
LAUTRayINI := TIniFile.Create(ProgramDirectory + C_LAUTRayINI);
|
LAUTRayINI := TIniFile.Create(ProgramDirectory + C_LAUTRayINI);
|
||||||
@ -1248,8 +1258,9 @@ begin
|
|||||||
szSection := fParentForm.Caption
|
szSection := fParentForm.Caption
|
||||||
else
|
else
|
||||||
szSection := 'My Application';
|
szSection := 'My Application';
|
||||||
If ((AnsiContainsText(szSection,{$I %FPCTARGETOS%}) = FALSE)
|
if ((AnsiContainsText(szSection,
|
||||||
AND (AnsiContainsText(szSection,szSuffix) = FALSE)) then
|
{$I %FPCTARGETOS%}
|
||||||
|
) = False) and (AnsiContainsText(szSection, szSuffix) = False)) then
|
||||||
szSection += szSuffix;
|
szSection += szSuffix;
|
||||||
WriteString(szSection, 'AppPrettyName', szSection);
|
WriteString(szSection, 'AppPrettyName', szSection);
|
||||||
WriteString(szSection, 'AppPath', ExtractFilename(fAppFilename));
|
WriteString(szSection, 'AppPath', ExtractFilename(fAppFilename));
|
||||||
@ -1334,14 +1345,14 @@ begin
|
|||||||
if not FileExistsUTF8(szDestLAUTrayPath + C_LAUTRayINI) then
|
if not FileExistsUTF8(szDestLAUTrayPath + C_LAUTRayINI) then
|
||||||
begin
|
begin
|
||||||
// Move C_LAUTRayINI from app folder to local <AppData> folder
|
// Move C_LAUTRayINI from app folder to local <AppData> folder
|
||||||
if CopyFile(szSourceLAUTrayPath, szDestLAUTrayPath + C_LAUTRayINI,
|
if FileUtil.CopyFile(szSourceLAUTrayPath, szDestLAUTrayPath + C_LAUTRayINI,
|
||||||
[cffOverwriteFile]) then
|
[cffOverwriteFile]) then
|
||||||
begin
|
begin
|
||||||
if fFireDebugEvent then
|
if fFireDebugEvent then
|
||||||
fOndebugEvent(Self, 'RelocateLauImportFile',
|
fOndebugEvent(Self, 'RelocateLauImportFile',
|
||||||
Format('Relocated %s from %s to %s', [C_LAUTRayINI,
|
Format('Relocated %s from %s to %s',
|
||||||
szSourceLAUTrayPath, szDestLAUTrayPath]));
|
[C_LAUTRayINI, szSourceLAUTrayPath, szDestLAUTrayPath]));
|
||||||
DeleteFile(szSourceLAUTrayPath);
|
SysUtils.DeleteFile(szSourceLAUTrayPath);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if fFireDebugEvent then
|
if fFireDebugEvent then
|
||||||
@ -1609,7 +1620,8 @@ begin
|
|||||||
// remotely shut down the app?
|
// remotely shut down the app?
|
||||||
if fSilentMode then
|
if fSilentMode then
|
||||||
begin
|
begin
|
||||||
If AppIsRunning(ExtractFileName(fAppFilename)) then KillApp(ExtractFileName(fAppFilename));
|
if AppIsRunning(ExtractFileName(fAppFilename)) then
|
||||||
|
KillApp(ExtractFileName(fAppFilename));
|
||||||
if fFireDebugEvent then
|
if fFireDebugEvent then
|
||||||
fOndebugEvent(Self, 'RemoteUpdateToNewVersion',
|
fOndebugEvent(Self, 'RemoteUpdateToNewVersion',
|
||||||
Format('Killing %s ready for update', [fAppFilename]));
|
Format('Killing %s ready for update', [fAppFilename]));
|
||||||
@ -1628,9 +1640,28 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TLazAutoUpdate.UpdateToNewVersion: boolean;
|
function TLazAutoUpdate.UpdateToNewVersion: boolean;
|
||||||
|
|
||||||
|
{$IFDEF WINDOWS}
|
||||||
|
// function RunAsAdmin(const Handle: Hwnd; const Path, Params: string): Boolean;
|
||||||
|
function RunAsAdmin(const Handle: THandle; const Path, Params: string): Boolean;
|
||||||
|
var
|
||||||
|
sei: TShellExecuteInfoA;
|
||||||
|
begin
|
||||||
|
FillChar(sei, SizeOf(sei), 0);
|
||||||
|
sei.cbSize := SizeOf(sei);
|
||||||
|
sei.Wnd := Handle;
|
||||||
|
sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
|
||||||
|
sei.lpVerb := 'runas';
|
||||||
|
sei.lpFile := PAnsiChar(Path);
|
||||||
|
sei.lpParameters := PAnsiChar(Params);
|
||||||
|
sei.nShow := SW_SHOWNORMAL;
|
||||||
|
Result := ShellExecuteExA(@sei);
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
var
|
var
|
||||||
cCount: cardinal;
|
cCount: cardinal;
|
||||||
szAppDir: string;
|
szAppDir: string;
|
||||||
|
szParams:String;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
szAppDir := AppendPathDelim(ExtractFilePath(fAppFilename));
|
szAppDir := AppendPathDelim(ExtractFilePath(fAppFilename));
|
||||||
@ -1642,7 +1673,6 @@ begin
|
|||||||
fOndebugEvent(Self, 'UpdateToNewVersion',
|
fOndebugEvent(Self, 'UpdateToNewVersion',
|
||||||
'Entering UpdateToNewVersion');
|
'Entering UpdateToNewVersion');
|
||||||
|
|
||||||
|
|
||||||
// Running update using updatehm?
|
// Running update using updatehm?
|
||||||
if not AppIsRunning(ExtractFileName(fAppFilename)) then
|
if not AppIsRunning(ExtractFileName(fAppFilename)) then
|
||||||
Result := DoSilentUpdate
|
Result := DoSilentUpdate
|
||||||
@ -1658,6 +1688,7 @@ begin
|
|||||||
Format(C_UpdaterMissing, [szAppDir + C_Updater]));
|
Format(C_UpdaterMissing, [szAppDir + C_Updater]));
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not DirectoryExistsUTF8(szAppDir + fUpdatesFolder) then
|
if not DirectoryExistsUTF8(szAppDir + fUpdatesFolder) then
|
||||||
begin
|
begin
|
||||||
if fShowDialogs then
|
if fShowDialogs then
|
||||||
@ -1672,16 +1703,42 @@ begin
|
|||||||
// remotely shut down the app?
|
// remotely shut down the app?
|
||||||
if fSilentMode then
|
if fSilentMode then
|
||||||
begin
|
begin
|
||||||
If AppIsRunning(ExtractFileName(fAppFilename)) then KillApp(ExtractFileName(fAppFilename));
|
if AppIsRunning(ExtractFileName(fAppFilename)) then
|
||||||
|
KillApp(ExtractFileName(fAppFilename));
|
||||||
if fFireDebugEvent then
|
if fFireDebugEvent then
|
||||||
fOndebugEvent(Self, 'UpdateToNewVersion',
|
fOndebugEvent(Self, 'UpdateToNewVersion',
|
||||||
Format('Killing %s ready for update', [fAppFilename]));
|
Format('Killing %s ready for update', [fAppFilename]));
|
||||||
end;
|
end;
|
||||||
|
{$IFDEF WINDOWS}
|
||||||
|
szParams:=ExtractFileName(fAppFilename);
|
||||||
|
szParams:=szParams + ' ' + fUpdatesFolder;
|
||||||
|
szParams:=szParams + ' ' + C_WhatsNewFilename;
|
||||||
|
szParams:=szParams + ' ' + fParentApplication.Title;
|
||||||
|
if (fCopyTree = True) then
|
||||||
|
szParams:=szParams + ' copytree';
|
||||||
|
if fFireDebugEvent then
|
||||||
|
fOndebugEvent(Self, 'UpdateToNewVersion',
|
||||||
|
Format('Executing %s', [szAppDir + C_UPDATER]));
|
||||||
|
RunAsAdmin(fParentForm.Handle,szAppDir + C_UPDATER, szParams);
|
||||||
|
|
||||||
|
// Check for C_WhatsNewFilename in the app directory in a LOOP
|
||||||
|
if fFireDebugEvent then
|
||||||
|
fOndebugEvent(Self, 'UpdateToNewVersion',
|
||||||
|
Format('Waiting for %s', [szAppDir + C_WhatsNewFilename]));
|
||||||
|
while not FileExistsUTF8(szAppDir + C_WhatsNewFilename) do
|
||||||
|
begin
|
||||||
|
fParentApplication.ProcessMessages;
|
||||||
|
Inc(CCount);
|
||||||
|
if cCount > 10000000 then
|
||||||
|
Break; // Get out of jail in case updatehm.exe fails to copy file
|
||||||
|
end;
|
||||||
|
{$ELSE}
|
||||||
// Update and re-start the app
|
// Update and re-start the app
|
||||||
FUpdateHMProcess := TAsyncProcess.Create(nil);
|
FUpdateHMProcess := TAsyncProcess.Create(nil);
|
||||||
try
|
try
|
||||||
|
// FUpdateHMProcess.Executable := AppendPathDelim(GetAppConfigDir(false)) + C_Updater;
|
||||||
FUpdateHMProcess.Executable := szAppDir + C_UPDATER;
|
FUpdateHMProcess.Executable := szAppDir + C_UPDATER;
|
||||||
|
// FUpdateHMProcess.CurrentDirectory := AppendPathDelim(GetAppConfigDir(false));
|
||||||
FUpdateHMProcess.CurrentDirectory := szAppDir;
|
FUpdateHMProcess.CurrentDirectory := szAppDir;
|
||||||
if not fSilentMode then
|
if not fSilentMode then
|
||||||
FUpdateHMProcess.ConsoleTitle :=
|
FUpdateHMProcess.ConsoleTitle :=
|
||||||
@ -1697,7 +1754,11 @@ begin
|
|||||||
if fFireDebugEvent then
|
if fFireDebugEvent then
|
||||||
fOndebugEvent(Self, 'UpdateToNewVersion',
|
fOndebugEvent(Self, 'UpdateToNewVersion',
|
||||||
Format('Executing %s', [szAppDir + C_UPDATER]));
|
Format('Executing %s', [szAppDir + C_UPDATER]));
|
||||||
|
TRY
|
||||||
FUpdateHMProcess.Execute;
|
FUpdateHMProcess.Execute;
|
||||||
|
EXCEPT
|
||||||
|
raise Exception.CreateFmt('Error %d: Run this application in Administrator mode or turn off UAC',[GetLastOSError]);
|
||||||
|
END;
|
||||||
|
|
||||||
// Check for C_WhatsNewFilename in the app directory in a LOOP
|
// Check for C_WhatsNewFilename in the app directory in a LOOP
|
||||||
if fFireDebugEvent then
|
if fFireDebugEvent then
|
||||||
@ -1710,15 +1771,15 @@ begin
|
|||||||
if cCount > 10000000 then
|
if cCount > 10000000 then
|
||||||
Break; // Get out of jail in case updatehm.exe fails to copy file
|
Break; // Get out of jail in case updatehm.exe fails to copy file
|
||||||
end;
|
end;
|
||||||
|
finally
|
||||||
finally
|
|
||||||
FUpdateHMProcess.Free;
|
FUpdateHMProcess.Free;
|
||||||
if not fSilentMode then
|
end;
|
||||||
fParentForm.Close;
|
{$ENDIF}
|
||||||
end;
|
|
||||||
if fFireDebugEvent then
|
if fFireDebugEvent then
|
||||||
fOndebugEvent(Self, 'UpdateToNewVersion',
|
fOndebugEvent(Self, 'UpdateToNewVersion',
|
||||||
'Success');
|
'Success');
|
||||||
|
if not fSilentMode then
|
||||||
|
fParentForm.Close;
|
||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1914,297 +1975,38 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{ End of class members}
|
{ End of class members}
|
||||||
|
function DownloadHTTP(URL, TargetFile: string;
|
||||||
function DownloadHTTPStream(URL: string; Buffer: TStream; fDebugMode: boolean): boolean;
|
var ReturnCode, DownloadSize: integer; bIsSourceForge, fDebugmode: boolean): boolean;
|
||||||
// Download file; retry if necessary.
|
|
||||||
const
|
|
||||||
MaxRetries = 3;
|
|
||||||
var
|
|
||||||
RetryAttempt: integer;
|
|
||||||
HTTPGetResult: boolean;
|
|
||||||
begin
|
|
||||||
Result := False;
|
|
||||||
RetryAttempt := 1;
|
|
||||||
HTTPGetResult := False;
|
|
||||||
while ((HTTPGetResult = False) and (RetryAttempt < MaxRetries)) do
|
|
||||||
begin
|
|
||||||
HTTPGetResult := HttpGetBinary(URL, Buffer);
|
|
||||||
//Application.ProcessMessages;
|
|
||||||
WaitFor(100 * RetryAttempt);
|
|
||||||
// Sleep(100 * RetryAttempt);
|
|
||||||
RetryAttempt := RetryAttempt + 1;
|
|
||||||
end;
|
|
||||||
if HTTPGetResult = False then
|
|
||||||
if fDebugmode then
|
|
||||||
raise Exception.Create(C_CannotLoadFromRemote);
|
|
||||||
Buffer.Position := 0;
|
|
||||||
if Buffer.Size = 0 then
|
|
||||||
if fDebugmode then
|
|
||||||
raise Exception.Create(C_DownloadIsEmpty)
|
|
||||||
else
|
|
||||||
Result := True;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function SFDirectLinkURL(URL: string; Document: TMemoryStream): string;
|
|
||||||
{
|
|
||||||
Transform this part of the body:
|
|
||||||
<noscript>
|
|
||||||
<meta http-equiv="refresh" content="5; url=http://downloads.sourceforge.net/project/base64decoder/base64decoder/version%202.0/b64util.zip?r=&ts=1329648745&use_mirror=kent">
|
|
||||||
</noscript>
|
|
||||||
into a valid URL:
|
|
||||||
http://downloads.sourceforge.net/project/base64decoder/base64decoder/version%202.0/b64util.zip?r=&ts=1329648745&use_mirror=kent
|
|
||||||
}
|
|
||||||
const
|
|
||||||
Refresh = '<meta http-equiv="refresh"';
|
|
||||||
URLMarker = 'url=';
|
|
||||||
var
|
|
||||||
Counter : integer;
|
|
||||||
HTMLBody : TStringList;
|
|
||||||
RefreshStart : integer;
|
|
||||||
URLStart : integer;
|
|
||||||
begin
|
|
||||||
HTMLBody := TStringList.Create;
|
|
||||||
try
|
|
||||||
HTMLBody.LoadFromStream(Document);
|
|
||||||
for Counter := 0 to HTMLBody.Count - 1 do
|
|
||||||
begin
|
|
||||||
// This line should be between noscript tags and give the direct download locations:
|
|
||||||
RefreshStart := Ansipos(Refresh, HTMLBody[Counter]);
|
|
||||||
if RefreshStart > 0 then
|
|
||||||
begin
|
|
||||||
URLStart := AnsiPos(URLMarker, HTMLBody[Counter]) + Length(URLMarker);
|
|
||||||
if URLStart > RefreshStart then
|
|
||||||
begin
|
|
||||||
// Look for closing "
|
|
||||||
URL := Copy(HTMLBody[Counter], URLStart,
|
|
||||||
PosEx('"', HTMLBody[Counter], URLStart + 1) - URLStart);
|
|
||||||
//infoln('debug: new url after sf noscript:');
|
|
||||||
//infoln(URL);
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
HTMLBody.Free;
|
|
||||||
end;
|
|
||||||
Result := URL;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function SourceForgeURL(URL: string; fDebugmode: boolean;
|
|
||||||
var AReturnCode: integer): string;
|
|
||||||
// Detects sourceforge download and tries to deal with
|
|
||||||
// redirection, and extracting direct download link.
|
|
||||||
// Thanks to
|
|
||||||
// Ocye: http://lazarus.freepascal.org/index.php/topic,13425.msg70575.html#msg70575
|
|
||||||
// http://downloads.sourceforge.net/project/lazautoupdate/updates/updatepackwin32.ini?r=&ts=1481210267&use_mirror=heanet
|
|
||||||
const
|
|
||||||
SFProjectPart = '//sourceforge.net/projects/';
|
|
||||||
SFFilesPart = '/files/';
|
|
||||||
SFDownloadPart ='/download';
|
|
||||||
var
|
|
||||||
HTTPSender: THTTPSend;
|
|
||||||
i, j: integer;
|
|
||||||
FoundCorrectURL: boolean;
|
|
||||||
SFDirectory: string; //Sourceforge directory
|
|
||||||
SFDirectoryBegin: integer;
|
|
||||||
SFFileBegin: integer;
|
|
||||||
SFFilename: string; //Sourceforge name of file
|
|
||||||
SFProject: string;
|
|
||||||
SFProjectBegin: integer;
|
|
||||||
begin
|
|
||||||
// Detect SourceForge download; e.g. from URL
|
|
||||||
// 1 2 3 4 5 6 7 8 9
|
|
||||||
// 1234557890123456789012345578901234567890123455789012345678901234557890123456789012345578901234567890
|
|
||||||
// http://sourceforge.net/projects/base64decoder/files/base64decoder/version%202.0/b64util.zip/download
|
|
||||||
// ^^^project^^^ ^^^directory............^^^ ^^^file^^^
|
|
||||||
FoundCorrectURL := True; //Assume not a SF download
|
|
||||||
i := Pos(SFProjectPart, URL);
|
|
||||||
if i > 0 then
|
|
||||||
begin
|
|
||||||
// Possibly found project; now extract project, directory and filename parts.
|
|
||||||
SFProjectBegin := i + Length(SFProjectPart);
|
|
||||||
j := PosEx(SFFilesPart, URL, SFProjectBegin);
|
|
||||||
if (j > 0) then
|
|
||||||
begin
|
|
||||||
SFProject := Copy(URL, SFProjectBegin, j - SFProjectBegin);
|
|
||||||
SFDirectoryBegin := PosEx(SFFilesPart, URL, SFProjectBegin) + Length(SFFilesPart);
|
|
||||||
if SFDirectoryBegin > 0 then
|
|
||||||
begin
|
|
||||||
// Find file
|
|
||||||
// URL might have trailing arguments... so: search for first
|
|
||||||
// /download coming up from the right, but it should be after
|
|
||||||
// /files/
|
|
||||||
i := RPos(SFDownloadPart, URL);
|
|
||||||
// Now look for previous / so we can make out the file
|
|
||||||
// This might perhaps be the trailing / in /files/
|
|
||||||
SFFileBegin := RPosEx('/', URL, i - 1) + 1;
|
|
||||||
|
|
||||||
if SFFileBegin > 0 then
|
|
||||||
begin
|
|
||||||
SFFilename := Copy(URL, SFFileBegin, i - SFFileBegin);
|
|
||||||
//Include trailing /
|
|
||||||
SFDirectory := Copy(URL, SFDirectoryBegin, SFFileBegin - SFDirectoryBegin);
|
|
||||||
// if fdebugmode then SHowMessage('SFFilename=' + SFFilename);
|
|
||||||
// if fdebugmode then SHowMessage('SFDirectory=' + SFDirectory);
|
|
||||||
FoundCorrectURL := False;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if not FoundCorrectURL then
|
|
||||||
begin
|
|
||||||
try
|
|
||||||
// Rewrite URL if needed for Sourceforge download redirection
|
|
||||||
// Detect direct link in HTML body and get URL from that
|
|
||||||
HTTPSender := THTTPSend.Create;
|
|
||||||
//Who knows, this might help:
|
|
||||||
HTTPSender.UserAgent :=
|
|
||||||
'curl/7.21.0 (i686-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.18';
|
|
||||||
while not FoundCorrectURL do
|
|
||||||
begin
|
|
||||||
HTTPSender.HTTPMethod('GET', URL);
|
|
||||||
// if fdebugmode then showmessagefmt('Return code is %d',[HTTPSender.Resultcode]);
|
|
||||||
// SEE: http_ReturnCodes.txt
|
|
||||||
case HTTPSender.Resultcode of
|
|
||||||
301, 302, 307:
|
|
||||||
begin
|
|
||||||
for i := 0 to HTTPSender.Headers.Count - 1 do
|
|
||||||
Begin
|
|
||||||
// if fdebugmode then SHowMessage('Header string=' + HTTPSender.Headers.Strings[i]);
|
|
||||||
if (Pos('Location: ', HTTPSender.Headers.Strings[i]) > 0) or
|
|
||||||
(Pos('location: ', HTTPSender.Headers.Strings[i]) > 0) then
|
|
||||||
begin
|
|
||||||
// if fdebugmode then SHowMessage('Header string=' + LeftStr(HTTPSender.Headers.Strings[i],Length( HTTPSender.Headers.Strings[i]) div 2));
|
|
||||||
//if fdebugmode then SHowMessage('Header string=' + RightStr(HTTPSender.Headers.Strings[i],Length( HTTPSender.Headers.Strings[i]) div 2));
|
|
||||||
j := Pos('use_mirror=', HTTPSender.Headers.Strings[i]);
|
|
||||||
if j > 0 then
|
|
||||||
URL :=
|
|
||||||
'http://' + RightStr(HTTPSender.Headers.Strings[i],
|
|
||||||
length(HTTPSender.Headers.Strings[i]) - j - 10) +
|
|
||||||
'downloads.sourceforge.net/project/' + SFProject +
|
|
||||||
'/' + SFDirectory + SFFilename
|
|
||||||
else
|
|
||||||
URL := StringReplace(HTTPSender.Headers.Strings[i],
|
|
||||||
'Location: ', '', []);
|
|
||||||
HTTPSender.Clear;//httpsend
|
|
||||||
FoundCorrectURL := True;
|
|
||||||
AReturnCode := HTTPSender.Resultcode;
|
|
||||||
break; //out of rewriting loop
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
100..200:
|
|
||||||
begin
|
|
||||||
//Could be a sourceforge timer/direct link page, but...
|
|
||||||
if AnsiPos('Content-Type: text/html', HTTPSender.Headers.Text) > 0 then
|
|
||||||
begin
|
|
||||||
// find out... it's at least not a binary
|
|
||||||
URL := SFDirectLinkURL(URL, HTTPSender.Document);
|
|
||||||
end;
|
|
||||||
FoundCorrectURL := True; //We're done by now
|
|
||||||
AReturnCode := HTTPSender.Resultcode;
|
|
||||||
end;
|
|
||||||
500:
|
|
||||||
begin
|
|
||||||
// if fDebugMode then ShowMessageFmt(C_Error500, [HTTPSender.ResultCode]);
|
|
||||||
AReturnCode := HTTPSender.Resultcode;
|
|
||||||
Break;
|
|
||||||
end;
|
|
||||||
//Raise Exception.Create('No internet connection available');
|
|
||||||
//Internal Server Error ('+aURL+')');
|
|
||||||
404:
|
|
||||||
begin
|
|
||||||
// if fDebugMode then ShowMessageFmt(C_Error404, [HTTPSender.ResultCode]);
|
|
||||||
AReturnCode := HTTPSender.Resultcode;
|
|
||||||
Break;
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
raise Exception.Create(C_DownloadFailedErrorCode +
|
|
||||||
IntToStr(HTTPSender.ResultCode) + ' (' + HTTPSender.ResultString + ')');
|
|
||||||
end;//case
|
|
||||||
end;//while
|
|
||||||
finally
|
|
||||||
AReturnCode := HTTPSender.Resultcode;
|
|
||||||
HTTPSender.Free;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
Result := URL;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function DownloadHTTP(URL, TargetFile: string; var ReturnCode, DownloadSize: integer;
|
|
||||||
bIsSourceForge, fDebugmode: boolean): boolean;
|
|
||||||
// Download file; retry if necessary.
|
// Download file; retry if necessary.
|
||||||
// Deals with SourceForge download links
|
// Deals with SourceForge download links
|
||||||
// Could use Synapse HttpGetBinary, but that doesn't deal
|
|
||||||
// with result codes (i.e. it happily downloads a 404 error document)
|
|
||||||
const
|
const
|
||||||
MaxRetries = 3;
|
MaxRetries = 3;
|
||||||
var
|
var
|
||||||
HTTPGetResult : boolean;
|
HTTPClient: TFPHTTPClient;
|
||||||
HTTPSender : THTTPSend;
|
HTTPGetResult: boolean;
|
||||||
RetryAttempt,i : integer;
|
RetryAttempt, i: integer;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
RetryAttempt := 1;
|
RetryAttempt := 1;
|
||||||
//Optional: mangling of Sourceforge file download URLs; see below.
|
HTTPClient := TFPHTTPClient.Create(nil);
|
||||||
if bIsSourceForge then
|
if bIsSourceForge then
|
||||||
begin
|
begin
|
||||||
URL := SourceForgeURL(URL, fDebugMode, ReturnCode); //Deal with sourceforge URLs
|
HTTPClient.AllowRedirect:=True;
|
||||||
// if fDebugMode then ShowMessage(LeftStr(URL,Length(URL) div 2));
|
|
||||||
// if fDebugMode then ShowMessage(RightStr(URL,Length(URL) div 2));
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// ReturnCode may not be useful, but it's provided here
|
// ReturnCode may not be useful, but it's provided here
|
||||||
HTTPSender := THTTPSend.Create;
|
|
||||||
try
|
try
|
||||||
try
|
try
|
||||||
// Try to get the file
|
// Try to get the file
|
||||||
HTTPGetResult := HTTPSender.HTTPMethod('GET', URL);
|
HTTPClient.Get(URL, TargetFile);
|
||||||
|
ReturnCode := HTTPClient.ResponseStatusCode;
|
||||||
while (HTTPGetResult = False) and (RetryAttempt < MaxRetries) do
|
DownloadSize := Filesize(TargetFile);
|
||||||
begin
|
|
||||||
WaitFor(500 * RetryAttempt);
|
|
||||||
// sleep(500 * RetryAttempt);
|
|
||||||
HTTPGetResult := HTTPSender.HTTPMethod('GET', URL);
|
|
||||||
RetryAttempt := RetryAttempt + 1;
|
|
||||||
end;
|
|
||||||
// If we have an answer from the server, check if the file
|
|
||||||
// was sent to us
|
|
||||||
ReturnCode := HTTPSender.Resultcode;
|
|
||||||
DownloadSize := HTTPSender.DownloadSize;
|
|
||||||
ShowMessageFmt('DownloadHTTP Return code=%d',[HTTPSender.Resultcode]);
|
|
||||||
ShowMessageFmt('DownloadHTTP Download Size=%d',[HTTPSender.DownloadSize]);
|
|
||||||
case HTTPSender.Resultcode of
|
|
||||||
100..299:
|
|
||||||
begin
|
|
||||||
with TFileStream.Create(TargetFile, fmCreate or fmOpenWrite) do
|
|
||||||
try
|
|
||||||
Seek(0, soFromBeginning);
|
|
||||||
CopyFrom(HTTPSender.Document, 0);
|
|
||||||
finally
|
|
||||||
Free;
|
|
||||||
end;
|
|
||||||
Result := True;
|
|
||||||
end; //informational, success
|
|
||||||
301: // moved permanently
|
|
||||||
begin
|
|
||||||
URL:=SourceForgeURL(URL,TRUE,ReturnCode);
|
|
||||||
ShowMessage(URL);
|
|
||||||
end;
|
|
||||||
302..399:
|
|
||||||
Result := False; //redirection. Not implemented, but could be.
|
|
||||||
400..499: Result := False; //client error; 404 not found etc
|
|
||||||
500..599: Result := False; //internal server error
|
|
||||||
else
|
|
||||||
Result := False; //unknown code
|
|
||||||
end;
|
|
||||||
except
|
except
|
||||||
// We don't care for the reason for this error; the download failed.
|
// We don't care for the reason for this error; the download failed.
|
||||||
Result := False;
|
Result := False;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
HTTPSender.Free;
|
HTTPClient.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<CONFIG>
|
<CONFIG>
|
||||||
<ProjectOptions>
|
<ProjectOptions>
|
||||||
<Version Value="9"/>
|
<Version Value="10"/>
|
||||||
<General>
|
<General>
|
||||||
<Flags>
|
<Flags>
|
||||||
<MainUnitHasCreateFormStatements Value="False"/>
|
<MainUnitHasCreateFormStatements Value="False"/>
|
||||||
@ -13,8 +13,11 @@
|
|||||||
<UseAppBundle Value="False"/>
|
<UseAppBundle Value="False"/>
|
||||||
<ResourceType Value="res"/>
|
<ResourceType Value="res"/>
|
||||||
<XPManifest>
|
<XPManifest>
|
||||||
<ExecutionLevel Value="1"/>
|
<DpiAware Value="True"/>
|
||||||
|
<ExecutionLevel Value="highestAvailable"/>
|
||||||
<UIAccess Value="True"/>
|
<UIAccess Value="True"/>
|
||||||
|
<TextName Value="Minesadorada.Lazarus.UpdateHM"/>
|
||||||
|
<TextDesc Value="Console updating app"/>
|
||||||
</XPManifest>
|
</XPManifest>
|
||||||
</General>
|
</General>
|
||||||
<i18n>
|
<i18n>
|
||||||
@ -22,50 +25,17 @@
|
|||||||
</i18n>
|
</i18n>
|
||||||
<VersionInfo>
|
<VersionInfo>
|
||||||
<UseVersionInfo Value="True"/>
|
<UseVersionInfo Value="True"/>
|
||||||
<RevisionNr Value="14"/>
|
<MinorVersionNr Value="1"/>
|
||||||
<StringTable Comments="updatehm -h for list of parameters" CompanyName="minesadorada@charcodelvalle.com" FileDescription="Console updater for LazAutoUpdate component" InternalName="updatehm" LegalCopyright="LGPLv2" OriginalFilename="updatehm.exe" ProductName="LazAutoUpdate" ProductVersion="0.0.13.0"/>
|
<StringTable Comments="updatehm -h for list of parameters" CompanyName="minesadorada@charcodelvalle.com" FileDescription="Console updater for LazAutoUpdate component" InternalName="updatehm" LegalCopyright="LGPLv2" OriginalFilename="updatehm.exe" ProductName="LazAutoUpdate" ProductVersion="0.0.13.0"/>
|
||||||
</VersionInfo>
|
</VersionInfo>
|
||||||
<BuildModes Count="6">
|
<BuildModes Count="5">
|
||||||
<Item1 Name="Default" Default="True"/>
|
<Item1 Name="DebugWin32" Default="True"/>
|
||||||
<Item2 Name="Debug">
|
<Item2 Name="Win32 Release">
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
<Version Value="11"/>
|
<Version Value="11"/>
|
||||||
<PathDelim Value="\"/>
|
<PathDelim Value="\"/>
|
||||||
<Target>
|
<Target>
|
||||||
<Filename Value="updates\updatehm"/>
|
<Filename Value="compiled\win32\updatehmwin32"/>
|
||||||
</Target>
|
|
||||||
<SearchPaths>
|
|
||||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
|
||||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
|
||||||
</SearchPaths>
|
|
||||||
<Parsing>
|
|
||||||
<SyntaxOptions>
|
|
||||||
<IncludeAssertionCode Value="True"/>
|
|
||||||
</SyntaxOptions>
|
|
||||||
</Parsing>
|
|
||||||
<CodeGeneration>
|
|
||||||
<Checks>
|
|
||||||
<IOChecks Value="True"/>
|
|
||||||
<RangeChecks Value="True"/>
|
|
||||||
<OverflowChecks Value="True"/>
|
|
||||||
<StackChecks Value="True"/>
|
|
||||||
</Checks>
|
|
||||||
</CodeGeneration>
|
|
||||||
<Linking>
|
|
||||||
<Debugging>
|
|
||||||
<DebugInfoType Value="dsDwarf2Set"/>
|
|
||||||
<UseHeaptrc Value="True"/>
|
|
||||||
<UseExternalDbgSyms Value="True"/>
|
|
||||||
</Debugging>
|
|
||||||
</Linking>
|
|
||||||
</CompilerOptions>
|
|
||||||
</Item2>
|
|
||||||
<Item3 Name="Win32 Release">
|
|
||||||
<CompilerOptions>
|
|
||||||
<Version Value="11"/>
|
|
||||||
<PathDelim Value="\"/>
|
|
||||||
<Target>
|
|
||||||
<Filename Value="..\updatehmcompiled\win32\updatehm"/>
|
|
||||||
</Target>
|
</Target>
|
||||||
<SearchPaths>
|
<SearchPaths>
|
||||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
@ -87,13 +57,13 @@
|
|||||||
<LinkSmart Value="True"/>
|
<LinkSmart Value="True"/>
|
||||||
</Linking>
|
</Linking>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
</Item3>
|
</Item2>
|
||||||
<Item4 Name="Win64 Release">
|
<Item3 Name="Win64 Release">
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
<Version Value="11"/>
|
<Version Value="11"/>
|
||||||
<PathDelim Value="\"/>
|
<PathDelim Value="\"/>
|
||||||
<Target>
|
<Target>
|
||||||
<Filename Value="..\updatehmcompiled\win64\updatehm"/>
|
<Filename Value="compiled\win64\updatehmwin64"/>
|
||||||
</Target>
|
</Target>
|
||||||
<SearchPaths>
|
<SearchPaths>
|
||||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
@ -115,13 +85,13 @@
|
|||||||
<LinkSmart Value="True"/>
|
<LinkSmart Value="True"/>
|
||||||
</Linking>
|
</Linking>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
</Item4>
|
</Item3>
|
||||||
<Item5 Name="Linux32 Release">
|
<Item4 Name="Linux32 Release">
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
<Version Value="11"/>
|
<Version Value="11"/>
|
||||||
<PathDelim Value="\"/>
|
<PathDelim Value="\"/>
|
||||||
<Target>
|
<Target>
|
||||||
<Filename Value="..\updatehmcompiled\linux32\updatehm"/>
|
<Filename Value="compiled\linux32\updatehmlinux32"/>
|
||||||
</Target>
|
</Target>
|
||||||
<SearchPaths>
|
<SearchPaths>
|
||||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
@ -146,13 +116,13 @@
|
|||||||
<CustomOptions Value="-FLC:\NewPascal\cross\lib\i386-linux\ld-linux.so.2"/>
|
<CustomOptions Value="-FLC:\NewPascal\cross\lib\i386-linux\ld-linux.so.2"/>
|
||||||
</Other>
|
</Other>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
</Item5>
|
</Item4>
|
||||||
<Item6 Name="Linux64 Release">
|
<Item5 Name="Linux64 Release">
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
<Version Value="11"/>
|
<Version Value="11"/>
|
||||||
<PathDelim Value="\"/>
|
<PathDelim Value="\"/>
|
||||||
<Target>
|
<Target>
|
||||||
<Filename Value="..\updatehmcompiled\linux64\updatehm"/>
|
<Filename Value="compiled\linux64\updatehmlinux64"/>
|
||||||
</Target>
|
</Target>
|
||||||
<SearchPaths>
|
<SearchPaths>
|
||||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
@ -174,8 +144,11 @@
|
|||||||
</Debugging>
|
</Debugging>
|
||||||
<LinkSmart Value="True"/>
|
<LinkSmart Value="True"/>
|
||||||
</Linking>
|
</Linking>
|
||||||
|
<Other>
|
||||||
|
<CustomOptions Value="-FcUTF8"/>
|
||||||
|
</Other>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
</Item6>
|
</Item5>
|
||||||
</BuildModes>
|
</BuildModes>
|
||||||
<PublishOptions>
|
<PublishOptions>
|
||||||
<Version Value="2"/>
|
<Version Value="2"/>
|
||||||
@ -205,15 +178,32 @@
|
|||||||
<Version Value="11"/>
|
<Version Value="11"/>
|
||||||
<PathDelim Value="\"/>
|
<PathDelim Value="\"/>
|
||||||
<Target>
|
<Target>
|
||||||
<Filename Value="updatehm"/>
|
<Filename Value="compiled\win32debug\updatehmwin32debug"/>
|
||||||
</Target>
|
</Target>
|
||||||
<SearchPaths>
|
<SearchPaths>
|
||||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
</SearchPaths>
|
</SearchPaths>
|
||||||
|
<Parsing>
|
||||||
|
<SyntaxOptions>
|
||||||
|
<IncludeAssertionCode Value="True"/>
|
||||||
|
</SyntaxOptions>
|
||||||
|
</Parsing>
|
||||||
|
<CodeGeneration>
|
||||||
|
<Checks>
|
||||||
|
<IOChecks Value="True"/>
|
||||||
|
<RangeChecks Value="True"/>
|
||||||
|
<OverflowChecks Value="True"/>
|
||||||
|
<StackChecks Value="True"/>
|
||||||
|
</Checks>
|
||||||
|
<TargetCPU Value="i386"/>
|
||||||
|
<TargetOS Value="win32"/>
|
||||||
|
</CodeGeneration>
|
||||||
<Linking>
|
<Linking>
|
||||||
<Debugging>
|
<Debugging>
|
||||||
<GenerateDebugInfo Value="False"/>
|
<DebugInfoType Value="dsDwarf2Set"/>
|
||||||
|
<UseHeaptrc Value="True"/>
|
||||||
|
<UseExternalDbgSyms Value="True"/>
|
||||||
</Debugging>
|
</Debugging>
|
||||||
</Linking>
|
</Linking>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
|
@ -67,7 +67,7 @@ uses
|
|||||||
const
|
const
|
||||||
C_AppPrettyName = 'Lazarus Auto-Updater';
|
C_AppPrettyName = 'Lazarus Auto-Updater';
|
||||||
C_WhatsNewFileName = 'whatsnew.txt';
|
C_WhatsNewFileName = 'whatsnew.txt';
|
||||||
C_Version = '0.0.14';
|
C_Version = '0.0.15';
|
||||||
C_UpdatesDirectory = 'updates';
|
C_UpdatesDirectory = 'updates';
|
||||||
C_LogFileName = 'updatehmlog.txt';
|
C_LogFileName = 'updatehmlog.txt';
|
||||||
C_LAUTRayINI = 'lauimport.ini';
|
C_LAUTRayINI = 'lauimport.ini';
|
||||||
@ -120,9 +120,13 @@ var
|
|||||||
begin
|
begin
|
||||||
if ParamCount = 0 then
|
if ParamCount = 0 then
|
||||||
begin
|
begin
|
||||||
|
WriteLn('==========================================================');
|
||||||
Writeln(LineEnding + '==== updatehm v' + C_Version +
|
Writeln(LineEnding + '==== updatehm v' + C_Version +
|
||||||
' - an lazautoupdate application ====');
|
' - an lazautoupdate application ====');
|
||||||
Writeln('Usage: updatehm exename.exe [updatesfoldername] [whatnewfilename] [exePrettyName] [copytree]');
|
Writeln('Usage: updatehm exename.exe [updatesfoldername] [whatnewfilename] [exePrettyName] [copytree]');
|
||||||
|
WriteLn('==========================================================');
|
||||||
|
WriteLn('Press any key to continue');
|
||||||
|
ReadLn;
|
||||||
Halt;
|
Halt;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -135,6 +139,8 @@ begin
|
|||||||
WriteLn('optional parameters are');
|
WriteLn('optional parameters are');
|
||||||
WriteLn('-h or /h - this screen');
|
WriteLn('-h or /h - this screen');
|
||||||
WriteLn('==========================================================');
|
WriteLn('==========================================================');
|
||||||
|
WriteLn('Press any key to continue');
|
||||||
|
ReadLn;
|
||||||
Halt;
|
Halt;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -2,15 +2,15 @@
|
|||||||
<CONFIG>
|
<CONFIG>
|
||||||
<ProjectSession>
|
<ProjectSession>
|
||||||
<PathDelim Value="\"/>
|
<PathDelim Value="\"/>
|
||||||
<Version Value="9"/>
|
<Version Value="10"/>
|
||||||
<BuildModes Active="Win64 Release"/>
|
<BuildModes Active="Linux64 Release"/>
|
||||||
<Units Count="25">
|
<Units Count="25">
|
||||||
<Unit0>
|
<Unit0>
|
||||||
<Filename Value="updatehm.lpr"/>
|
<Filename Value="updatehm.lpr"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<IsVisibleTab Value="True"/>
|
<IsVisibleTab Value="True"/>
|
||||||
<TopLine Value="114"/>
|
<TopLine Value="132"/>
|
||||||
<CursorPos X="36" Y="292"/>
|
<CursorPos X="41" Y="144"/>
|
||||||
<UsageCount Value="76"/>
|
<UsageCount Value="76"/>
|
||||||
<Loaded Value="True"/>
|
<Loaded Value="True"/>
|
||||||
</Unit0>
|
</Unit0>
|
||||||
@ -134,26 +134,23 @@
|
|||||||
<UsageCount Value="10"/>
|
<UsageCount Value="10"/>
|
||||||
</Unit21>
|
</Unit21>
|
||||||
<Unit22>
|
<Unit22>
|
||||||
<Filename Value="..\..\..\..\..\lazarus\components\lazutils\lazutf8.pas"/>
|
<Filename Value="D:\lazarus\components\lazutils\lazutf8.pas"/>
|
||||||
<UnitName Value="LazUTF8"/>
|
<UnitName Value="LazUTF8"/>
|
||||||
<EditorIndex Value="3"/>
|
<EditorIndex Value="-1"/>
|
||||||
<UsageCount Value="10"/>
|
<UsageCount Value="10"/>
|
||||||
<Loaded Value="True"/>
|
|
||||||
</Unit22>
|
</Unit22>
|
||||||
<Unit23>
|
<Unit23>
|
||||||
<Filename Value="..\..\..\..\..\lazarus\components\lazutils\lazfileutils.pas"/>
|
<Filename Value="D:\lazarus\components\lazutils\lazfileutils.pas"/>
|
||||||
<UnitName Value="LazFileUtils"/>
|
<UnitName Value="LazFileUtils"/>
|
||||||
<EditorIndex Value="2"/>
|
<EditorIndex Value="-1"/>
|
||||||
<TopLine Value="61"/>
|
<TopLine Value="61"/>
|
||||||
<UsageCount Value="10"/>
|
<UsageCount Value="10"/>
|
||||||
<Loaded Value="True"/>
|
|
||||||
</Unit23>
|
</Unit23>
|
||||||
<Unit24>
|
<Unit24>
|
||||||
<Filename Value="..\..\..\..\..\fpc\packages\fcl-process\src\process.pp"/>
|
<Filename Value="D:\fpc\packages\fcl-process\src\process.pp"/>
|
||||||
<EditorIndex Value="1"/>
|
<EditorIndex Value="-1"/>
|
||||||
<TopLine Value="76"/>
|
<TopLine Value="76"/>
|
||||||
<UsageCount Value="10"/>
|
<UsageCount Value="10"/>
|
||||||
<Loaded Value="True"/>
|
|
||||||
</Unit24>
|
</Unit24>
|
||||||
</Units>
|
</Units>
|
||||||
<JumpHistory Count="28" HistoryIndex="27">
|
<JumpHistory Count="28" HistoryIndex="27">
|
||||||
|
Binary file not shown.
Reference in New Issue
Block a user