4

sorry for my english.

Hi my installer will download files , by the addition of " IDP : Download plugin for Inno Setup," and I have a problem because they are downloaded in .zip format so need to be extracted , whether it is possible to be unpacked where the application ? It is an add-on or something? Please help.

Jens A. Koch
  • 39,862
  • 13
  • 113
  • 141
michal3210
  • 117
  • 1
  • 7
  • 1
    Possible duplicate of http://stackoverflow.com/questions/6065364/how-to-get-inno-setup-to-unzip-a-file-it-installed-all-as-part-of-the-one-inst –  Apr 05 '15 at 20:45
  • Yes, but this is not the effect that I want , and of that person did not benefit from the said allowance. – michal3210 Apr 05 '15 at 20:51

1 Answers1

4

You can ship the unzip tool of your choice and use it for extraction.

I tend to ship "7za" (the command-line version of 7zip), because i found out that it's extraction speed is really good (and better than unzip).

Firstly, you integrate the extraction tool into your installer.

    [Files]
    Source: ..\utils\unzip\7za.exe; DestDir: {tmp}; Flags: dontcopy
    Source: and some zip files ...

Note the dontcopy. This will not copy the file to the user system during the normal file copying stage, but statically compile the file into the installation.

Secondly, you might add a little DoUnzip helper method to your [Code] section.

It will use the tool from the temp folder.

procedure DoUnzip(source: String; targetdir: String);
var 
    unzipTool: String;
    ReturnCode: Integer;
begin
    // source contains tmp constant, so resolve it to path name
    source := ExpandConstant(source);

    unzipTool := ExpandConstant('{tmp}\7za.exe');

    if not FileExists(unzipTool)
    then MsgBox('UnzipTool not found: ' + unzipTool, mbError, MB_OK)
    else if not FileExists(source)
    then MsgBox('File was not found while trying to unzip: ' + source, mbError, MB_OK)
    else begin
         if Exec(unzipTool, ' x "' + source + '" -o"' + targetdir + '" -y',
                 '', SW_HIDE, ewWaitUntilTerminated, ReturnCode) = false
         then begin
             MsgBox('Unzip failed:' + source, mbError, MB_OK)
         end;
    end;
end;

Thirdly, you extract the unzip tool, then the zips and then you simply use the DoUnzip() method on the zips. These commands are for the [Code] section.

  // extract 7za to temp folder
  ExtractTemporaryFile('7za.exe');

  // extract the zip to the temp folder (when included in the installer)
  // skip this, when the file is downloaded with IDP to the temp folder
  //ExtractTempraryFile('app.zip);

  targetPath := ExpandConstant('{tmp}\');

  // unzip the zip in the tempfolder to your application target path
  DoUnzip(targetPath + 'app.zip', ExpandConstant('{app}'));
Jens A. Koch
  • 39,862
  • 13
  • 113
  • 141
  • 3
    I would go either this way, or import e.g. 7-Zip DLL functions (if it's possible). There is yet one more option that I *stole* from [`this lazy`](http://www.scriptkitties.com/innounzip/) plugin which uses Windows Shell for this task. With that it's enough to write [`something like this`](http://pastebin.com/qWxvTFDx) when using late binding. However, I'm not sure when was added built-in support for archives in Shell (not speaking about quite poor performance). – TLama Apr 07 '15 at 00:18
  • Using the CopyHere functionality of Shell.Application for unzipping is a nice trick. It saves you from shipping an additional tool. Also a pretty compact little wrapper function - i like it. Because of "noprogressbox", i wonder if it's possible to grab the extraction progress from CopyHere and display it. // The downside of my approach is, that it locks the Innosetup window up during the time of the extraction and i still haven't found a way around that. – Jens A. Koch Apr 07 '15 at 00:27
  • 1
    Not for this script object method. I believe there will be some way with early binding (since Vista something around `IFileOperation` interface, I think). A flat function (if there is one) would almost surely require a callback with the `stdcall` calling convention, which would in turn require external plugin (InnoCallback.dll), so no big deal again. – TLama Apr 07 '15 at 01:51
  • @TLama I'm trying to use your code from pastebin, but I get an error on the CopyHere line that reads "NIL interface exception." Do you know why this could be? – Joel Christophel May 31 '16 at 06:25