2

I have large file ( needs to be extracted ) in App Directory.

[Files]
Source: "Installer Files\out\abc.data"; DestDir: "{userappdata}\App"; Flags: ignoreversion onlyifdoesntexist

Zip file on server is abc.zip (contains abc.data)

Looked at answers here -

Download file - https://stackoverflow.com/a/66100456/2323607

Unzip https://stackoverflow.com/a/44382324/2323607

Not sure how to integrate them together

Q1 - Only download zip abc.zip, if file abc.data doesn't exist at "{userappdata}\App" location

Q2 - Once zip file is downloaded, extract abc.data it to location "{userappdata}\App"

Amod Gokhale
  • 2,346
  • 4
  • 17
  • 32

1 Answers1

1

By default InnoSetup will check if a file exists. You can however, change the behavior by adding a function that does the check for you. If you don't do that, it seems InnoSetup will always check for the presence of the abc.data file in the source directory.

[Files]
Source: "{tmp}\abc.data"; DestDir: "{userappdata}\App"; Flags: external; Check: ExtractedFileNeedsInstallation


[Code]
function ExtractedFileNeedsInstallation: Boolean;
var 
  TargetPath: String; 
begin  
  TargetPath := ExpandConstant('{userappdata}')+'\App\abc.data';
  Result := not FileExists(TargetPath);
  Log(Format('ExtractedFileNeedsInstallation: %d', [Result]));  
end;

For the download function, you can first check if the file exists, in which case you skip the download:

  if CurPageID = wpReady then begin
      if (not ExtractedFileNeedsInstallation) then
      begin
          Result := True;
      end
      else

and if the file is downloaded, then unzip the file when the download is complete:

try
  DownloadPage.Download;
  Temp := ExpandConstant('{tmp}');
  UnZip(Temp+'\abc.zip', 'abc.data', Temp);
  Result := True;
except

Full InnoSetup example with most parts taken from the linked download code and unzip code:

[Setup]
AppName=DownloadExample
AppVersion=1.0
DefaultDirName=DownloadTest
[Files]
Source: "{tmp}\abc.data"; DestDir: "{userappdata}\App"; Flags: external; Check: ExtractedFileNeedsInstallation

[Code]
const
  NO_PROGRESS_BOX = 4;
  RESPOND_YES_TO_ALL = 16;
procedure UnZip(ZipPath, FileName, TargetPath: string); 
var
  Shell: Variant;
  ZipFile: Variant;
  Item: Variant;
  TargetFolder: Variant;
begin
  Shell := CreateOleObject('Shell.Application');

  ZipFile := Shell.NameSpace(ZipPath);
  if VarIsClear(ZipFile) then
    RaiseException(Format('Cannot open ZIP file "%s" or does not exist', [ZipPath]));

  Item := ZipFile.ParseName(FileName);
  if VarIsClear(Item) then
    RaiseException(Format('Cannot find "%s" in "%s" ZIP file', [FileName, ZipPath]));

  TargetFolder := Shell.NameSpace(TargetPath);
  if VarIsClear(TargetFolder) then
    RaiseException(Format('Target path "%s" does not exist', [TargetPath]));

  TargetFolder.CopyHere(Item, NO_PROGRESS_BOX or RESPOND_YES_TO_ALL);
end;

function ExtractedFileNeedsInstallation: Boolean;
var 
  TargetPath: String; 
begin  
  TargetPath := ExpandConstant('{userappdata}')+'\App\abc.data';
  Result := not FileExists(TargetPath);
  Log(Format('ExtractedFileNeedsInstallation: %d', [Result]));  
end;

var
  DownloadPage: TDownloadWizardPage;

function OnDownloadProgress(const Url, FileName: String; const Progress, ProgressMax: Int64): Boolean;

begin
  if Progress = ProgressMax then
  begin
    Log(Format('Successfully downloaded file to {tmp}: %s', [FileName]));
  end;
  Result := True;
end;

procedure InitializeWizard;
begin
  DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), @OnDownloadProgress);
end;

function NextButtonClick(CurPageID: Integer): Boolean;
var  
  Temp: String;
begin
  if CurPageID = wpReady then begin
      if (not ExtractedFileNeedsInstallation) then
      begin
          Result := True;
      end
      else
      begin
          DownloadPage.Clear;
          DownloadPage.Add('http://37.120.179.6/test/thomas/upload/abc.zip', 'abc.zip', '');
          DownloadPage.Show;
          try
            try
              DownloadPage.Download;
              Temp := ExpandConstant('{tmp}');
              UnZip(Temp+'\abc.zip', 'abc.data', Temp);
              Result := True;
            except
              SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbCriticalError, MB_OK, IDOK);
              Result := False;
            end;
          finally
            DownloadPage.Hide;
          end;
      end;
  end else
    Result := True;
end;
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
  • thank you for answer. It answers both the questions. i'm trying to understand the code and what i was doing wrong. Can you please help me understand one thing. With my code.. maybe i was sending incorrect third parameter in unzip funtion ( i thought of sennding {userappdata}\app folder ). From where unzip gets the correct path? – Amod Gokhale Mar 04 '22 at 10:00
  • 1
    @AmodGokhale: the first parameter to Unzip() is the full path of the ZIP file including file name. The second parameter is the file you want to unzip from that zip file. The third parameter is the directory where to put the extracted file. The linked question was about extracting a single file from a ZIP file. I thought that's what you wanted. – Thomas Weller Mar 04 '22 at 10:51
  • we are passing {tmp} as third parameter for extracted file. However it correctly extracts it to {userappdata}\app ( this is exactly what i need ). Maybe i'm not able to understand it correctly. But thank you so much for your answer. Its really helpful. – Amod Gokhale Mar 04 '22 at 12:14
  • 1
    @AmodGokhale: it extracts to `{tmp}` but the file installs from `Source: "{tmp}\abc.data";` to `DestDir: "{userappdata}\App";` I guess you could also extract it directly into `{userappdata}`, but I'm not sure whether the file would be uninstalled then. – Thomas Weller Mar 04 '22 at 12:42
  • aha.. i understand the code now. Thanks much. award button is disabled for 18 more hours... i'll update, once its enabled. – Amod Gokhale Mar 04 '22 at 12:45
  • @AmodGokhale: no problem. Maybe even better answers arrive. – Thomas Weller Mar 04 '22 at 12:46
  • 1
    Use `ExpandConstant(CurrentFilename)` instead of `ExpandConstant('{userappdata}')+'\App\abc.data'` to avoid repeating the path. – Martin Prikryl Mar 16 '22 at 11:06
  • 1
    @MartinPrikryl: it seems that a lot of people don't know about [CurrentFilename](https://jrsoftware.org/ishelp/index.php?topic=isxfunc_currentfilename). It's also not used in the answers I assembled this answer from. Glad to get feedback from an expert. – Thomas Weller Mar 16 '22 at 12:13