spiegel-keyman/windows/src/desktop/setup/Keyman.Setup.System.ResourceDownloader.pas

136 lines
3.5 KiB
ObjectPascal

{**
* Wrapper for THttpClient for downloading resources with progress.
*}
unit Keyman.Setup.System.ResourceDownloader;
interface
uses
Keyman.Setup.System.InstallInfo,
UfrmDownloadProgress;
type
TResourceDownloader = class sealed
private
FDownloadURL: string;
FDownloadFilename: string;
FInstallInfo: TInstallInfo;
FSilent: Boolean;
function DownloadFile(const ADownloadURL, ADownloadFilename: string): Boolean;
procedure DownloadFileCallback(AOwner: TfrmDownloadProgress; var Result: Boolean);
constructor Create(AInstallInfo: TInstallInfo; ASilent: Boolean);
public
class function Execute(AInstallInfo: TInstallInfo; ALocation: TInstallInfoFileLocation; ASilent: Boolean): Boolean;
end;
implementation
uses
System.Classes,
System.SysUtils,
Vcl.Controls,
Winapi.Windows,
httpuploader,
SetupStrings,
Upload_Settings;
{ TResourceDownloader }
{**
* After installation, location will have its properties set to iilLocal;
* the file is downloaded into TempPath, so will be removed post install.
*}
class function TResourceDownloader.Execute(AInstallInfo: TInstallInfo; ALocation: TInstallInfoFileLocation; ASilent: Boolean): Boolean;
var
rd: TResourceDownloader;
begin
rd := TResourceDownloader.Create(AInstallInfo, ASilent);
try
Result := rd.DownloadFile(ALocation.Url, AInstallInfo.TempPath + ALocation.Path);
if Result then
begin
ALocation.UpgradeToLocalPath(AInstallInfo.TempPath);
end;
finally
rd.Free;
end;
end;
constructor TResourceDownloader.Create(AInstallInfo: TInstallInfo; ASilent: Boolean);
begin
inherited Create;
FInstallInfo := AInstallInfo;
FSilent := ASilent;
end;
function TResourceDownloader.DownloadFile(const ADownloadURL, ADownloadFilename: String): Boolean;
var
frmDownloadProgress: TfrmDownloadProgress;
begin
FDownloadURL := ADownloadURL;
FDownloadFilename := ADownloadFilename;
if FSilent then
DownloadFileCallback(nil, Result)
else
begin
{ Download the redistributable }
frmDownloadProgress := TfrmDownloadProgress.Create(nil);
try
frmDownloadProgress.Caption := FInstallInfo.Text(ssDownloadingTitle, [ExtractFileName(ADownloadFilename)]);
frmDownloadProgress.Callback := DownloadFileCallback;
Result := frmDownloadProgress.ShowModal = mrOk;
finally
frmDownloadProgress.Free;
end;
end;
end;
procedure TResourceDownloader.DownloadFileCallback(AOwner: TfrmDownloadProgress; var Result: Boolean);
var
http: THTTPUploader;
Stream: TStream;
FTempFilename: string;
begin
Result := False;
FTempFilename := FDownloadFilename + '.download';
http := THTTPUploader.Create(nil);
try
http.ShowUI := not FSilent;
if Assigned(AOwner) then
begin
http.OnStatus := AOwner.HTTPStatus;
http.OnCheckCancel := AOwner.HTTPCheckCancel;
end;
http.Request.SetURL(FDownloadURL);
http.Upload;
Result := http.Response.StatusCode = 200;
if Result then
begin
Stream := TFileStream.Create(FTempFilename, fmCreate);
try
Stream.Write(http.Response.PMessageBody^, http.Response.MessageBodyLength);
finally
Stream.Free;
end;
end;
if FileExists(FTempFilename) then
begin
if Result then
begin
if FileExists(FDownloadFilename) then
System.SysUtils.DeleteFile(FDownloadFilename);
RenameFile(FTempFilename, FDownloadFilename);
end
else
System.SysUtils.DeleteFile(FTempFilename);
end;
finally
http.Free;
end;
end;
end.